/*! BUI - v2.0.0 - 2022-03-13 09:03:17 
Copyright (c): kevin.huang  https://gitee.com/kevin-huang/bui2.0.git (qq:757723114) 
Released under MIT License*/
(function ( global, factory) {
//   "use strict";
	if ( typeof module === "object" && typeof module.exports === "object" ) {
		module.exports = global.document ?
			factory( global, true ) :
			function( w ) {
				if ( !w.document ) {
					throw new Error( "Bui requires a window with a document" );
				}
				return factory( w );
			};
	} else {
		  factory( global );
	}  
})( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
//   "use strict";
  var $B = window["$B"] ?  window["$B"] : {};

var UTILS = {
    stopDefaultctxMenu: function () {
        if (typeof UTILS.CTXMENUTIMER !== "undefined") {
            return;
        }
        let $body = $B.getBody();
        let fn = function () {
            return false;
        };
        $B.DomUtils.addListener($body, "edit.contextmenu", fn);
        UTILS.CTXMENUTIMER = setTimeout(function () {
            UTILS.CTXMENUTIMER = undefined;
            $B.DomUtils.removeListener($body, "edit.contextmenu", fn);
        }, 500);
    },
    getDPI: function () {
        if (this.DPI) {
            return this.DPI;
        }
        if (window.screen.deviceXDPI != undefined) {
            this.DPI = window.screen.deviceXDPI;
        } else {
            let tmpNode = document.createElement("DIV");
            tmpNode.style.cssText = "width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden";
            document.body.appendChild(tmpNode);
            this.DPI = parseInt(tmpNode.offsetWidth);
            tmpNode.parentNode.removeChild(tmpNode);
        }
        this.DPI;
    },
     /*** 96dpi：1英寸=96 1cm=37.795276  一英寸=0.0254m=2.54cm 
     * ***/
    px2cm:function(px){
        let dpi = this.getDPI();
        let tmp = dpi.div(2.54);
        let res = px.div(tmp);
        return res;
    },
    cm2px:function(cm){
        let dpi = this.getDPI();
        let tmp = dpi.div(2.54);
        let res = cm.mul(tmp);
        return res;
    },
    /**
    * 获取一个段落元素
    * ***/
    createPEl: function (notCHild) {
        let id = $B.generateDateUUID();
        let $e = $B.DomUtils.createEl('<div class="p_element" id="' + id + '" style="' + editCfg.pElementCss + '"></div>');
        if (!notCHild) {
            let $s = this.createSpanEl();
            $B.DomUtils.append($e, $s);
        }
        return $e;
    },
    createSpanEl: function () {
        let id = $B.generateDateUUID();
        let $e = $B.DomUtils.createEl('<span class="p_span"  id="' + id + '"  style="' + editCfg.spanCss + '">\u200B</span>');
        return $e;
    },
    getPelDefCss: function () {
        var cssMap = {
            "pbackgorund": undefined,
            "lhrate": undefined,
            "indent": undefined,
            "line-height": undefined,       //行高
            "padding-left": undefined,       //左边距
            "padding-right": undefined,      //右边距
            "padding-top": undefined,         //上边距
            "padding-bottom": undefined,       //下边距
            "border-top": undefined,         //上边框
            "border-right": undefined,         //上边框
            "border-bottom": undefined,         //上边框
            "border-left": undefined,       //上边框
            "text-align": undefined,               //对齐
            "border-bottom": undefined,
            "border-left": undefined,
            "border-right": undefined,
            "border-top": undefined
        };
        return cssMap;
    },
    getSpanDefcss: function () {
        var cssMap = {
            "font-weight": undefined, //加粗
            "font-style": undefined,     //斜体
            "text-decoration": undefined,    //underline下划线，line-through中划线
            "vertical-align": undefined,      //上标super ；下标sub
            "font-family": undefined,        //字体
            "font-size": undefined,          //字体大小
            "letter-spacing": undefined,    //字体间距  
            "color": undefined,              //字体颜色
            "background-color": undefined   //背景色
        };
        return cssMap;
    },
    removeAfterEls: function (firstp) {
        let nextp = firstp.nextSibling;
        while (nextp) {
            let tmpp = nextp.nextSibling;
            $B.DomUtils.remove(nextp);
            nextp = tmpp;
        }
    },
    /**
 * 获取行内最大字体
 * ***/
    getMaxFontSize: function ($p, max) {
        var childs = $p.children;
        for (let i = 0; i < childs.length; i++) {
            let child = childs[i];
            let obj = $B.style2cssObj(child);
            if (obj["font-size"]) {
                let v = parseFloat(obj["font-size"]);
                if (!max) {
                    max = v;
                } else {
                    if (v > max) {
                        max = v;
                    }
                }
            }
            let nv = this.getMaxFontSize(child, max);
            if (nv && nv > max) {
                max = nv;
            }
        }
        return max;
    },
    /**
    * 获取段落的行高比，及最大字体
    */
    getLineHightData: function ($p) {
        let max = this.getMaxFontSize($p);
        let lineHeight = $B.DomUtils.css($p, "line-height");
        let r = lineHeight / max;
        return {
            lh: lineHeight,
            max: max,
            r: r
        };
    },
    getFirstTextEL: function ($el) {
        let txt = $el.innerText.replaceAll("\u200B", "");
        if (txt.length > 0) {
            return $el;
        }
        if ($el.nextSibling) {
            return this.getFirstTextEL($el.nextSibling);
        }
        return $el;
    },
    setBorderMap: function (map, borderObj) {
        if (typeof map.size === "undefined") {
            map.size = borderObj.size;
        } else if (borderObj.size !== map.size) {
            map.size = undefined;
        }
        if (typeof map.style === "undefined") {
            map.style = borderObj.style;
        } else if (borderObj.style !== map.style) {
            map.style = undefined;
        }
        if (typeof map.color === "undefined") {
            map.color = borderObj.color;
        } else if (borderObj.color !== map.color) {
            map.color = undefined;
        }
    },
    setBorderCss: function ($el, borderCss) {
        let cssObj = $B.style2cssObj($el);
        let keys = Object.keys(cssObj);
        for (let i = 0; i < keys.length; i++) {
            let key = keys[i];
            if (key.indexOf("border") > -1) {
                delete cssObj[key];
            }
        }
        $B.extendObjectFn(cssObj, borderCss);
        let style = $B.cssObj2string(cssObj);
        $B.DomUtils.attribute($el, { style: style });
    },
    /**
     * 边框样式转 边框对象
     * * */
    border2obj: function (border, not2int) {
        let r = {
            size: undefined,
            style: undefined,
            color: undefined
        };
        if (border) {
            border = border.replace(/,\s+/g, ",");
            let tmp = border.split(/\s+/g);
            r.size = not2int ? tmp[0] : parseInt(tmp[0].replace("px", ""));
            r.style = tmp[1];
            r.color = tmp[2].replaceAll(",", ", ");
        }
        return r;
    },
    getPelCss: function ($el, skipBorder) {
        let lData = this.getLineHightData($el);
        let lineHight = lData.lh;
        let paddingLeft = $B.DomUtils.css($el, "padding-left");
        let paddingRight = $B.DomUtils.css($el, "padding-right");
        let paddingTop = $B.DomUtils.css($el, "padding-top");
        let paddingBottom = $B.DomUtils.css($el, "padding-bottom");
        let textAlign = $B.DomUtils.css($el, "text-align");
        let textIndent = $B.DomUtils.css($el, "text-indent");
        let indent = parseFloat(textIndent.replace("px", ""));
        let $fc = this.getFirstTextEL($el.firstChild);
        let fs = parseFloat($B.DomUtils.css($fc, "font-size").replace("px", ""));
        let char = indent / fs;
        let ret = {
            "pbackgorund": $B.DomUtils.css($el, "background-color"),
            "line-height": lineHight,
            "padding-left": paddingLeft,
            "padding-right": paddingRight,
            "padding-top": paddingTop,
            "padding-bottom": paddingBottom,
            "text-align": textAlign,
            "text-indent": textIndent,
            "lhrate": lData.r,
            "indent": char
        };
        if (!skipBorder) {
            let border = this.getBorder($el);
            ret["border-bottom"] = border["border-bottom"];
            ret["border-left"] = border["border-left"],
                ret["border-right"] = border["border-right"];
            ret["border-top"] = border["border-top"];
        }
        return ret;
    },
    getBorder: function ($el, exclude) {
        var bsize = $B.DomUtils.css($el, "border-top-width") + "px";
        var bstyle = $B.DomUtils.css($el, "border-top-style");
        var bcolor = $B.DomUtils.css($el, "border-top-color");
        var val = bsize + " " + bstyle + " " + bcolor;
        if (bsize === 0 || bstyle === "none") {
            val = undefined;
        }
        var ret = {};
        if (!exclude || exclude !== "top") {
            ret["border-top"] = val;
        }
        bsize = $B.DomUtils.css($el, "border-right-width") + "px";
        bstyle = $B.DomUtils.css($el, "border-right-style");
        bcolor = $B.DomUtils.css($el, "border-right-color");
        val = bsize + " " + bstyle + " " + bcolor;
        if (bsize === 0 || bstyle === "none") {
            val = undefined;
        }
        if (!exclude || exclude !== "right") {
            ret["border-right"] = val;
        }
        bsize = $B.DomUtils.css($el, "border-bottom-width") + "px";
        bstyle = $B.DomUtils.css($el, "border-bottom-style");
        bcolor = $B.DomUtils.css($el, "border-bottom-color");
        val = bsize + " " + bstyle + " " + bcolor;
        if (bsize === 0 || bstyle === "none") {
            val = undefined;
        }
        if (!exclude || exclude !== "bottom") {
            ret["border-bottom"] = val;
        }
        bsize = $B.DomUtils.css($el, "border-left-width") + "px";
        bstyle = $B.DomUtils.css($el, "border-left-style");
        bcolor = $B.DomUtils.css($el, "border-left-color");
        val = bsize + " " + bstyle + " " + bcolor;
        if (bsize === 0 || bstyle === "none") {
            val = undefined;
        }
        if (!exclude || exclude !== "left") {
            ret["border-left"] = val;
        }
        return ret;
    },
    setCssMapVal: function (cssMap, valObj, cssName) {
        if (typeof cssMap[cssName] === "undefined") {
            cssMap[cssName] = valObj[cssName];
        } else if (cssMap[cssName] !== null && cssMap[cssName] !== valObj[cssName]) {
            cssMap[cssName] = null;
        }
    },
    loopExtractCss: function ($el, cssMap, skipBorder) {
        if ($el.nodeName === "P") {
            this.extractPcss($el, cssMap, skipBorder);
            let childs = $el.children;
            for (let i = 0; i < childs.length; i++) {
                this.loopExtractCss(childs[i], cssMap, skipBorder);
            }
        } else if ($el.nodeName === "SPAN") {
            this.extractSpancss($el, cssMap);
        } else {
            let childs = $el.children;
            for (let i = 0; i < childs.length; i++) {
                this.loopExtractCss(childs[i], cssMap, skipBorder);
            }
        }
    },
    /**
    * 抽取段落样式
    * ***/
    extractPcss: function ($p, cssMap, skipBorder) {
        let v1 = this.getPelCss($p, skipBorder);
        this.setCssMapVal(cssMap, v1, "pbackgorund");//段落背景色        
        this.setCssMapVal(cssMap, v1, "text-align");//对齐
        this.setCssMapVal(cssMap, v1, "line-height");//行高
        this.setCssMapVal(cssMap, v1, "padding-left");//左边距
        this.setCssMapVal(cssMap, v1, "padding-right");//右边距
        this.setCssMapVal(cssMap, v1, "padding-top");//上边距
        this.setCssMapVal(cssMap, v1, "padding-bottom");//下边距 
        this.setCssMapVal(cssMap, v1, "text-indent");//缩进     
        this.setCssMapVal(cssMap, v1, "lhrate");//行高比例      
        this.setCssMapVal(cssMap, v1, "indent");//缩进字符 
        if (!skipBorder) {
            this.setCssMapVal(cssMap, v1, "border-top");//上边框
            this.setCssMapVal(cssMap, v1, "border-right");//上边框
            this.setCssMapVal(cssMap, v1, "border-bottom");//上边框
            this.setCssMapVal(cssMap, v1, "border-left");//左边框 
        }
    },
    /**
    * 抽取SPAN样式
    * ***/
    extractSpancss: function ($el, cssMap) {
        let v1 = this.getSpanCss($el);
        this.setCssMapVal(cssMap, v1, "font-weight");//加粗
        this.setCssMapVal(cssMap, v1, "font-style");//斜体
        this.setCssMapVal(cssMap, v1, "text-decoration");//underline下划线，line-through中划线
        this.setCssMapVal(cssMap, v1, "vertical-align");//上标super ；下标sub
        this.setCssMapVal(cssMap, v1, "font-family");//字体
        this.setCssMapVal(cssMap, v1, "font-size");//字体大小
        this.setCssMapVal(cssMap, v1, "letter-spacing");//字体间距 
        this.setCssMapVal(cssMap, v1, "color"); //字体颜色
        this.setCssMapVal(cssMap, v1, "background-color"); //背景色        
    },
    getSpanCss: function ($el) {
        let txtDesc = $B.DomUtils.css($el, "text-decoration");
        if (txtDesc.indexOf("none") >= 0) {
            txtDesc = undefined;
        }
        let ret = {
            "font-weight": $B.DomUtils.css($el, "font-weight"),           //加粗
            "font-style": $B.DomUtils.css($el, "font-style"),            //斜体
            "text-decoration": txtDesc,       //underline下划线，line-through中划线
            "vertical-align": $B.DomUtils.css($el, "vertical-align"),        //上标super ；下标sub
            "font-family": $B.DomUtils.css($el, "font-family"),           //字体
            "font-size": $B.DomUtils.css($el, "font-size"),             //字体大小
            "letter-spacing": $B.DomUtils.css($el, "letter-spacing"),        //字体间距  
            "color": $B.DomUtils.css($el, "color"),                 //字体颜色           
            "background-color": $B.DomUtils.css($el, "background-color")       //背景色
        };
        return ret;
    },
    getPanelEl: function () {
        return $B.DomUtils.createEl('<div style="width: auto; display: none;" class="k_edit_tools_tip_wrapper k_edit_tools_drop_wrapper k_box_size  k_box_shadow"><div class="k_edit_tools_drop_caret"><i class="fa fa-up-dir"></i></div><div class="k_edit_tools_drop_item_wrap" tabindex="0" _focus="true"></div></div>');
    },
    createCommPanel: function (opts) {
        let onClosed = opts.onClosed;
        css = opts.css,
            title = opts.title;
        let $panel = this.getPanelEl();
        if (css) {
            $B.DomUtils.css($panel, css);
        }
        let $wap = $panel.lastChild;
        let $b = $B.DomUtils.append($wap, "<div  style='position:relative;width:100%;border-top:30px solid #fff' class='k_box_size'></div>");
        let $h = $B.DomUtils.append($wap, "<div id='_dragable' class='_common_drag k_box_size' style='position:absolute;width:100%;height:30px;top:0;left:0;border-bottom:1px solid #dfdbdb;text-align:left;line-height:26px;' class='k_box_size'>" + title + "<span style='position:absolute;top:5px;right:3px;cursor:pointer;' id='_title_close'><i class='fa  fa-cancel-2'></i></span></div>");
        if (opts.title === "") {
            $b.style["border-top"] = "10px solid #fff";
            $h.style["height"] = "10px";
            $h.firstChild.style["top"] = "-5px";
            $h.firstChild.style["fontSize"] = "12px";
        }
        $B.DomUtils.append(document.body, $panel);
        if (opts.onCreated) {
            opts.onCreated($b)
        };
        let dragOpt = {
            notClearRange: true,
            isProxy: false,
            handler: "#_dragable"
        };
        $B.draggable($panel, dragOpt);
        let $c = $B.DomUtils.findbyId($h, "_title_close");
        $B.DomUtils.click($c, (e) => {
            let $el = e.target.parentNode.parentNode.parentNode.parentNode;
            $el.style.display = "none";
            if (onClosed) { onClosed($el); }
        });
        return $panel;
    },
    showPanel: function ($panel, pos) {
        $panel.style.top = "-1000px";
        $panel.style.left = "-1000px";
        $panel.style.display = "block";
        let width = $B.DomUtils.outerWidth($panel);
        let height = $B.DomUtils.outerHeight($panel);
        let bw = $B.DomUtils.width(document.body);
        let bh = $B.DomUtils.height(document.body);
        let maxLeft = pos.left + width + 12;
        if (maxLeft > bw) {
            pos.left = bw - width - 12;
        }
        let maxTop = pos.top + height + 20;
        let $icon = $panel.firstChild;
        if (maxTop > bh) {
            pos.top = pos.top - height - 20;
            $panel.style.borderBottom = "2px solid rgb(66, 66, 66)";
            $panel.style.borderTop = "1px solid #dfdbdb";
            $icon.style.top = (height - 5) + "px";
            $icon.firstChild.style.transform = "rotateZ(180deg)";
        } else {
            $icon.style.top = "-11px";
            $icon.firstChild.style.transform = "rotateZ(0deg)";
            $panel.style.borderTop = "2px solid rgb(66, 66, 66)";
            $panel.style.borderBottom = "none";
        }
        $panel.style.top = pos.top + "px";
        $panel.style.left = pos.left + "px";
    },
    createChildCtxMenu: function (id, list, onClick) {
        let $wap = $B.DomUtils.createEl("<div id='" + id + "' class='k_box_size k_box_shadow k_edit_ctx_menu' style='position:absolute;background:#fff;display:none;z-index:2147483647'></div>");
        for (let i = 0; i < list.length; i++) {
            $B.DomUtils.append($wap, "<span class='_ctx_it' fn='" + list[i].fn + "'>" + list[i].label + "</span>");
        }
        $B.DomUtils.click($wap, (e) => {
            if ($B.DomUtils.hasClass(e.target, "_ctx_it")) {
                onClick.call(e.target, $B.DomUtils.attr(e.target, "fn"));
            }
        });
        $B.DomUtils.mouseleave($wap, (e) => {
            e.target.style.display = "none";
        });
        $B.DomUtils.append(document.body, $wap);
        return $wap;
    },
    showCtxMenu: function ($ctx, el) {
        //console.log("showCtxMenu");
        $ctx.style.top = "-1000px";
        $ctx.style.left = "-1000px";
        $ctx.style.display = "block";
        let ctxw = $B.DomUtils.outerWidth($ctx);
        let ctxh = $B.DomUtils.outerHeight($ctx);

        let ofs = $B.DomUtils.offset(el);
        let w = $B.DomUtils.outerWidth(el) + 5;

        ofs.left = ofs.left + w;
        let bw = $B.DomUtils.width(document.body);
        let bh = $B.DomUtils.height(document.body);
        if ((ofs.left + ctxw) > bw) {
            ofs.left = ofs.left - w - ctxw;
        }
        if ((ofs.top + ctxh) > bh) {
            let h = $B.DomUtils.outerHeight(el);
            ofs.top = ofs.top - ctxh + h;
        }
        $ctx.style.top = ofs.top + "px";
        $ctx.style.left = ofs.left + "px";
    },
    isHightLight: function ($btn) {
        if ($B.DomUtils.hasClass($btn, editCfg.hightLightClz)) {
            return true;
        } else {
            return false;
        }
    },
    addHightLight: function ($btn) {
        $B.DomUtils.addClass($btn, editCfg.hightLightClz);
    },
    removeHightLight: function ($btn) {
        $B.DomUtils.removeClass($btn, editCfg.hightLightClz);
    },
    getBoldCss: function ($evEl) {
        let css;
        if (this.isHightLight($evEl)) {
            css = "normal";
            this.removeHightLight($evEl);
        } else {
            css = "bold";
            this.addHightLight($evEl);
        }
        return css;
    },
    fontWeightConver: function (spanCss) {
        if (spanCss["font-weight"] === "400") {
            spanCss["font-weight"] = "normal";
        } else {
            spanCss["font-weight"] = "bold";
        }
    },
    getitalicCss: function ($evEl) {
        let css;
        if (this.isHightLight($evEl)) {
            css = "normal";
            this.removeHightLight($evEl);
        } else {
            css = "italic";
            this.addHightLight($evEl);
        }
        return css;
    },
    indentPFn: function (indent, $p) {
        if (indent !== 0) {
            let $f = UTILS.getFirstTextEL($p);
            let size = parseFloat($B.DomUtils.css($f, "font-size").replace("px", ""));
            indent = indent * size;
        }
        $p.style.textIndent = indent + "px";
    },
    isEmptyEl: function (el) {
        let txt = el.innerText.replaceAll("\u200b", "");
        return txt === "";
    },
    createCtxItem: function (ctxMenus, $b, onCLick) {
        for (let i = 0; i < ctxMenus.length; i++) {
            let c = ctxMenus[i];
            $B.Dom.append($b, '<div fn="' + c.fn + '"  tabindex="0"  class="k_edit_tools_drop_item item" _focus="true"><i style="padding-right:6px;" class="fa ' + c.icon + '"></i>' + c.label + '</div>');
        }
        $B.Dom.click($b, (e) => {
            let el = e.target;
            if (el.nodeName === "I") {
                el = el.parentNode;
            }
            if ($B.Dom.hasClass(el, "item")) {
                onCLick(el, e);
            }
        });
    },
    removeBr: function ($p) {
        let brArr = $B.Dom.children($p, "br");
        for (let i = 0; i < brArr.length; i++) {
            $p.removeChild(brArr[i]);
        }
    },
    appendIfrPanel: function ($wap, onLoad) {
        let $ifr = $B.DomUtils.createEl('<iframe class="panel_ifr" frameborder="0" style="width:100%;height:100%;" scrolling="no"></iframe>');
        $B.DomUtils.append($wap, $ifr);
        let doc = $ifr.contentWindow.document;
        let childs = document.head.children;
        let source = [];
        for (let i = 0; i < childs.length; i++) {
            let child = childs[i];
            if (child.nodeName === "LINK" || child.nodeName === "SCRIPT") {
                if ($B.Dom.hasClass(child, "edit_source")) {
                    if (child.nodeName === "LINK") {
                        source.push(child.cloneNode(true));
                    } else {
                        let s = doc.createElement('script');
                        s.type = 'text/javascript';
                        s.src = child.src;
                        source.push(s);
                    }
                }
            }
        }
        let loading = source.length;
        let onLoadFn = function () {
            loading--;
        };
        var timetemp = new Date().getTime();
        var $body = doc.body;
        var $head = doc.head;
        for (let i = 0; i < source.length; i++) {
            let tag = source[i];
            if (tag.nodeName === "LINK") {
                tag.href = tag.href.indexOf("?") > 0 ? (tag.href + "&y=" + timetemp) : (tag.href + "?y=" + timetemp);
            } else {
                tag.src = tag.src.indexOf("?") > 0 ? (tag.src + "&y=" + timetemp) : (tag.src + "?y=" + timetemp);
            }
            tag.onload = onLoadFn;
            $B.Dom.append($head, source[i]);
        }
        let ivt = 0;
        let ivtr = setInterval(() => {
            if (ivt >= 100) {
                if (!this.ifrsourcelding) {
                    this.ifrsourcelding = $B.busyTip({
                        mask: true,
                        closeable: false, //是否关闭
                        title: editCfg.pagesCfg.waiting
                    });
                }
            }
            if (loading === 0) {
                clearInterval(ivtr);
                if (this.ifrsourcelding) {
                    this.ifrsourcelding.close();
                    this.ifrsourcelding = undefined;
                }
                onLoad($body, doc, $head);
            }
            ivt++;
            if (ivt > 2000) {
                clearInterval(ivtr);
                if (this.ifrsourcelding) {
                    this.ifrsourcelding.close();
                    this.ifrsourcelding = undefined;
                }
                $B.error(editCfg.pagesCfg.sourceErr);
            }
        }, 50);
    },
    runInnerJS: function ($head, _callInner, _returnInner, js) {
        window._callInner = _callInner;
        window._returnInner = _returnInner;
        let exeScript = document.createElement('script');
        exeScript.type = 'text/javascript';
        exeScript.innerHTML = js;
        $head.appendChild(exeScript);
        window._returnInner = undefined;
        window._callInner = undefined;
    },
    makePropFormAccor: function ($body, title, icon) {
        let $h = $B.Dom.append($body, "<h5 class='k_edit_prp_accr_title k_box_size'><span class='k_prp_title_span'>" + title + "</span><i style='position:absolute;top:6px;right:2px;' class='fa fa-angle-up'></i></h5>");
        if (icon) {
            $B.Dom.prepend($h, "<i class='fa " + icon + "'></i>");
        }
        let $table = $B.Dom.append($body, "<div style='padding:10px 2px 2px 12px;'></div>");
        if (!UTILS.accorFormEvs) {
            UTILS.accorFormEvs = {
                click: (e) => {
                    let nextEl = e.catpurer.nextSibling;
                    $B.toggle(nextEl, 159, () => {
                        let deg = "0"
                        if (nextEl.style.display === "none") {
                            deg = "180";
                        }
                        $B.animate(e.catpurer.lastChild, { "rotateZ": deg + "deg" }, 160);
                    });
                }
            };
        }
        $B.Dom.bind($h, UTILS.accorFormEvs);
        return $table;
    },
    isFindedInSelect:function($sel,val){
        let opts = $sel.children;
        let isFinded = false;
        for(let i =0 ;i < opts.length ;i++){
            if(opts[i].value === val){
                isFinded = true;
                break;
            }
        } 
        return isFinded;
    }
};
$B["Utils"] = UTILS;
class Stack extends $B.BaseControl {
    constructor(size) {
        super();
        this.record = new Array(size);
        this.size = size; //栈大小
        this.length = 0; //当前记录的长度
    }
    /**压入记录
    * 返回当前栈长度
    * **/
    push(data) {
        //栈满，移除底部一个记录
        if (this.length === this.size) {
            this.record.pop();
            this.length--;
        }
        var l = this.record.unshift(data);
        this.length++;
        if (this.length > this.size) {
            this.length = this.size;
        }
        return this.length;
    }
    /**记录出栈
     * 返回一个记录
     * **/
    pop() {
        this.length--;
        if (this.length < 0) {
            this.length = 0;
        }
        return this.record.shift();
    }
    /**清空栈**/
    clear() {
        this.record = new Array(this.size);
        this.length = 0;
    }
    /**循环记录**/
    each(fn) {
        var len = this.length;
        for (var i = 0; i < len; i++) {
            fn(this.record[i], i);
        }
    }
    /**
     * 获取当前栈大小
     * **/
     length() {
        return this.length;
    }
}
$B["Stack"] = Stack;

var svgIcon = {
    pen: '<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"  width="20" height="16"><path d="M871.34208 260.46976l-106.93632-106.96704c-24.41728-24.40192-64.11776-24.40192-88.53504 0l-449.95072 449.95072c-10.78784 10.80832-16.53248 24.63744-17.78688 38.79936l-62.83264 198.17472c-3.42016 11.09504-0.4608 23.15776 7.76192 31.3856 8.22272 8.20736 20.29056 11.20256 31.3856 7.76704l198.15424-62.86336c14.1568-1.23392 27.99616-6.98368 38.784-17.78688l449.95584-449.95584C895.75424 324.57216 895.75424 284.87168 871.34208 260.46976zM356.01408 760.94464l-133.39648 41.2928 41.3184-133.41696c0.42496-1.44896 0.64-2.89792 0.85504-4.36736l95.5904 95.59552C358.94784 760.27904 357.48352 760.47872 356.01408 760.94464zM388.19328 743.60832l-106.96192-106.96704 438.89152-438.8864 106.9568 106.96704L388.19328 743.60832z"  fill="#13227a"></path></svg>',
    left: '<svg style="width:16px;height:16px;position:relative;top:3px;cursor:pointer;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M783.872 542.122667l-0.042667-64.405334-477.610666-0.298666 225.28-225.322667-45.568-45.568L182.506667 509.952l303.829333 303.829333 45.525333-45.504-226.474666-226.453333 478.506666 0.298667z"></path></svg>',
    right: '<svg style="width:16px;height:16px;position:relative;top:3px;cursor:pointer;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink" ><defs><style type="text/css"></style></defs><path d="M214.677333 542.122667l0.042667-64.405334 477.653333-0.298666-225.301333-225.322667 45.568-45.568 303.424 303.424L512.213333 813.781333l-45.504-45.504 226.453334-226.453333-478.485334 0.298667z"></path></svg>',
    reset: '<svg style="width:16px;height:16px;position:relative;top:3px;cursor:pointer;" viewBox="0 0 1278 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M1272.447024 472.907505l-150.052574 149.245613a32.021415 32.021415 0 0 1-44.681788 0L928.777033 472.906505c-17.717123-20.478986-5.895708-27.925618 6.45368-39.716035h136.525243A441.782135 441.782135 0 0 0 253.257466 304.732828L178.791151 275.257287a521.555187 521.555187 0 0 1 973.731808 157.934183h113.56338a26.653681 26.653681 0 0 1 6.360685 39.716035zM202.713967 440.946087l150.022575 149.556598a26.622682 26.622682 0 0 1-6.45468 39.717034H216.366292a442.247112 442.247112 0 0 0 789.701915 120.700026l75.213278 29.787526A521.555187 521.555187 0 0 1 134.513343 630.219719h-118.994111c-12.411386-11.791416-24.170804-19.238048-6.453681-39.717034l148.935629-149.556598a32.641385 32.641385 0 0 1 44.712787 0z"></path></svg>'
};
var editCfg = {
    hightLightClz: 'k_edit_tools_hlight',
    undoSize: 20,//undo回退步骤数量
    label: {
        "backOut":'取消',
        "ensure":"确认",
        "pleaseFocus":"请先点击聚焦文本域！",
        "brushConfirm":"是否需要复制段落样式？",   
        "noTitle":'否',
        "yesTitle":'是',
        "brushTitle":"格式刷确认？",      
        "clearConfirm":"请确认清空内容！",
        "clearTitle":"清理格式选项",
        "clearTitle2":"请选择清理格式选项！",
        "clearSelect":"清理选择",
        "clearPlist":"清理段落",
        "clearAll":"清理所有",
        "tableEdit": "表格修改",
        "unsuport":"不支持的操作！",
        "wordspace": '文本间距',
        "paragraph": "段落设置",
        "insertTable": "插入表格",
        "insertTableTip": "x行y列，按左键确认插入",
        "anchorTitle": "全选",
        "splitTd": "拆分",
        "megerTd": "合并",
        "insertCol": "插入列",
        "insertRow": "插入行",
        "insertFile": '插入文件',
        "insertImg": '插入图片',
        "editImg": "修改图片",
        "borderImg":"图片边框",
        "insertVideo": '插入视频',
        "inputColRow": '请输入行列数量',
        "insertTableMsg": '单元格内容必须为空！',
        "insertLink": "插入超链接",
        "uploadError":'上传异常!',
        "availableInsert":'无效插入！请您先点击需要插入的区域！',
        "availableBrush":"无效格式刷，请先划选样式区"
    },
    imgMenus:[
        {
            "label": "删除",
            "icon": "fa-cancel",
            "fn": 'deleteImgFn'
        },
        {
            "label": "修改",
            "icon": "fa-edit",
            "fn": 'editImgFn'
        },{
            "label": "边框",
            "icon": "fa-check-empty",
            "fn": 'borderImgFn'
        }
    ],
    ctxMenus: [
        {
            "label": "插入表格",
            "icon": "fa-table",
            "fn": 'openInsertTable'
        },
        {
            "label": "插入文件",
            "icon": "fa-upload",
            "fn": 'openInsertFile'
        },
        {
            "label": "插入图片",
            "icon": "fa-file-image",
            "fn": 'openInsertImage'
        },
        {
            "label": "插入超链接",
            "icon": "fa-link",
            "fn": 'openInsertLink'
        },
        {
            "label": "插入表情",
            "icon": "fa-smile",
            "fn": 'openInsertEmotion'
        },
        {
            "label": "段落设置",
            "icon": "fa-doc-text",
            "fn": 'openGraph'
        }
    ],
    tableNoBorder: '1px dashed rgb(175, 201, 222)',
    tableCtx: {
        '_insert_op_tr': [
            { fn: "insertRight", label: '右侧插入列' },
            { fn: "insertLeft", label: '左侧插入列' },
            { fn: "insertUp", label: '上方插入行' },
            { fn: "insertDown", label: '下方插入行' },
            { fn: "insertTable", label: '插入表格' }
        ],
        '_delete_op_tr': [
            { fn: "removeRow", label: "删除行" },
            { fn: "removeCol", label: "删除列" },
            { fn: "removeContent", label: "删除内容" },
            { fn: "removeTable", label: "删除表格" }
        ]
    },
    tools: [        
        { fn: "importFn", label: '导入文档', icon: 'fa-upload-cloud' },
        { fn: "printFn", label: '导出Word', icon: 'fa-file-word' },
        { fn: "printFn", label: '导出Pdf', icon: 'fa-file-pdf' },        
        { fn: "printFn", label: '打印', icon: 'fa-print' },
        { fn: "saveFn", label: '保存', icon: 'fa-floppy' },
        { fn: "paintBrushFn", label: '格式刷', icon: 'fa-brush', region: true ,focus:true},
        { fn: "clearFn", label: '清空', icon: 'fa-trash-empty' },
        { fn: "eraserFn", label: '清除格式', icon: 'fa-eraser' },       
        { fn: "undoFn", label: '回退', icon: 'fa-ccw-1' },
        { fn: "redoFn", label: '重做', icon: 'fa-cw-1' },
        { fn: "boldFn", label: '加粗', icon: 'fa-bold', region: true ,focus:true},
        { fn: "italicFn", label: '斜体', icon: 'fa-italic', region: true ,focus:true},
        { fn: "underlineFn", label: '下划线', icon: 'fa-underline', region: true ,focus:true},
        { fn: "strikethroughFn", label: '删除线', icon: 'fa-strike', region: true ,focus:true},
        { fn: "superscriptFn", label: '上标', icon: 'fa-superscript', region: true ,focus:true},
        { fn: "subscriptFn", label: '下标', icon: 'fa-subscript', region: true,focus:true },
        { fn: "fontFamilyFn", label: '字体', icon: 'fa-angle-down', region: true,focus:true, opts: [{ label: '微软雅黑', value: '微软雅黑,Microsoft YaHei' }, { label: '宋体', value: '宋体,SimSun' }, { label: '楷体', value: '楷体,楷体_GB2312,SimKai' }, { label: '黑体', value: '黑体,SimHei' }, { label: '隶书', value: '隶书,SimLi' }] },
        { fn: "fontSizeFn", label: '字体大小', icon: 'fa-angle-down', region: true,focus:true, opts: [{ label: '9px', value: '9px' }, { label: '10px', value: '10px' }, { label: '11px', value: '11px' }, { label: '12px', value: '12px' }, { label: '13px', value: '13px' }, { label: '14px', value: '14px' }, { label: '16px', value: '16px' }, { label: '18px', value: '18px' }, { label: '20px', value: '20px' }, { label: '22px', value: '22px' }, { label: '24px', value: '24px' }, { label: '28px', value: '28px' }, { label: '32px', value: '32px' }, { label: '36px', value: '36px' }] },
        { fn: "fontTitleFn", label: '正文', icon: 'fa-angle-down', region: true,focus:true, opts: [{ label: '正文', value: '14px' }, { label: '标题1', value: '28px' }, { label: '标题2', value: '24px' }, { label: '标题3', value: '22px' }, { label: '标题4', value: '18px' }, { label: '标题5', value: '16px' }] },
        { fn: "fontSpaceFn", label: '文字间距', icon: 'fa-text-width-1', region: true,focus:true },
        { fn: "fontColorFn", label: '文字颜色', icon: 'fa-pencil', region: true,focus:true },
        { fn: "backgroundColorFn", label: '背景色', icon: 'fa-pencil-squared', region: true,focus:true },
        { fn: "paragraphFn", label: '段落设置', icon: 'fa-doc-text',focus:true },
        { fn: "insertTableFn", label: '插入表格', icon: 'fa-table',focus:true },
        { fn: "alignLeftFn", label: '左对齐', icon: 'fa-align-left',focus:true },
        { fn: "alignCenterFn", label: '居中对齐', icon: 'fa-align-center',focus:true },
        { fn: "alignRightFn", label: '右对齐', icon: 'fa-align-right',focus:true },
        { fn: "linkFn", label: '超链接', icon: 'fa-link',focus:true },
        { fn: "pictureFn", label: '插入图片', icon: 'fa-file-image',focus:true },
        { fn: "uploadFn", label: '上传文件', icon: 'fa-upload',focus:true },
        { fn: "orderListFn", label: '有序列表',focus:true, icon: 'fa-list-numbered' ,opts: [{ label: '数字[1]', value: '1' }, { label: '中文数字[一]', value: '一' }, { label: '字母[a]', value: 'a' }, { label: '无', value: '' }]},
        { fn: "unorderListFn", label: '无序列表',focus:true, icon: 'fa-list-bullet',opts: [{ label: '空心圆', value: 'fa-circle-empty' }, { label: '实心圆', value: 'fa-record' }, { label: '方块', value: 'fa-stop' },{label:'箭头',value:'fa-angle-double-right'}, { label: '无', value: '' }] },
        { fn: "emotionFn", label: '表情', icon: 'fa-smile',focus:true },
        { fn: "insertIconFn", label: '插入图标', icon: 'fa-heart-empty',focus:true },
        { fn: "insertFloatFn", label: '插入浮动文本/图片', icon: 'fa-docs',focus:true }
        // { fn: "videoFn", label: '插入视频', icon: 'fa-video' },
        // { fn: "mapFn", label: '插入地图', icon: 'fa-location-alt' },
        // { fn: "insertCodeFn", label: '插入代码', icon: 'fa-file-code' },
        // { fn: "flowFn", label: '绘制流程', icon: 'fa-shuffle' },
        // { fn: "sourceFn", label: '源码', icon: 'fa-code' },
        // { fn: "mobileFn", label: '手机模拟', icon: 'fa-eye' },
        // { fn: "previewFn", label: '预览', icon: 'fa-eye' },
        // { fn: "fullprintFn", label: '全屏', icon: 'fa-resize-full' },
        // { fn: "helpFn", label: '使用帮助', icon: 'fa-question' }
    ],
    mobiles: [{ size: "320 * 568", title: 'IPHONE4' },
    { size: "360 * 640", title: '三星S5' },
    { size: "375 * 667", title: 'IPHONE6', default: true },
    { size: "414 * 736", title: '华为P20' },
    { size: "375 * 812", title: 'IPHONEX' },
    { size: "768 * 1024", title: 'IPAD' }],
    textFontSize: "14px",
    chlist:['一','二','三','四','五','六','七','八','九','十'],
    enlist:['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'],
    pElementCss: 'line-height:21px;font-size:14px;padding:0px;cursor:text;margin:0px;width:auto;text-align:left;background-color:none;',
    spanCss: 'font-size:14px;font-family:Microsoft Yahei;color:#1c1c29;background-color:none;font-weight: normal;',
    lineCss: 'line-height: 3px;height: 3px;border-bottom: 1px solid #B2B2B2;border-top: none;border-left: none;border-right: none;margin-top: 4px;margin-bottom: 4px;cursor: pointer',
    preview: 'preview.html',//预览页面 
    /**浮动文本启用的功能***/
    floatEidtor: {
        'save': true, 'bold': true, "paintBrush": true, "fontTitle": true,
        'italic': true, 'underline': true, 'strikethrough': true, 'superscript': true, 'subscript': true, 'fontFamily': true, 'insertIcon': true, 'eraser': true,
        'fontSize': true, 'fontSpace': true, 'fontColor': true, 'alignCenter': true, 'alignLeft': true, 'alignRight': true, 'video': true, 'split': true,
        'insertTable': true, 'flow': true, 'upload': true, 'link': true, 'emotion': true, 'insertCode': true, 'paragraph': true, 'backgroundColor': true, 'map': true
    },
    fontSpaceForm: "<div><p><span style='width:40%;padding-left:9px'>段落:<span style='padding-left:5px;'><input  style='cursor:pointer;' checked='checked' type='radio' id='for_p' name='target'/></span></span><span style='width:40%;padding-left:9px'> 选区:<span style='padding-left:5px;'><input id='for_s' style='cursor:pointer;' type='radio' name='target'/></span></span></p>"
        + "<p><span style='cursor:pointer' class='label reduce ev'>" + svgIcon.left + "减小</span><span style='cursor:pointer' class='label addplus ev'>" + svgIcon.right + "增大</span><span style='cursor:pointer' class='label reset ev'>" + svgIcon.reset + "重置</span></p>"
        + "<p><span class='label'>输入值</span><span  class='label'><input id='txtinput' placeholder='像数' type='text' value='0' style='width:50px'/></span><span  class='label'><button id='surebtn'>确认</button></span></p>"
        + "</div>",
    inputColRowForm: "<span>行：<input style='width:100px' id='row_input' value='2' type='text'/><span style='padding-left:20px;'>列：</span><input value='2' id='col_input'  style='width:100px' type='text'/></span>",
    iconForm: '<div><div class="clearfix"><div style="float:left;line-height:28px;" class="clearfix"><div style="float:left;">颜色：<i unbindcolorev="" id="icon_color" style="border:1px solid #f5f5f5;padding-left:12px;color:#FFFFFF;background-color:#7E7E7E;cursor:pointer;" class="fa fa-brush"></i></div>  <div style="float:left;padding-left:20px;">大小：</div><div style="float:left;height:21px;" id="_slider"></div></div><div id="_tip_wrap" style="float:left;width:50px;height:24px;line-height:24px;padding-left:12px;">12px</div></div>' +
        '<div class="clearfix" id="_icons" style="padding-top:20px;"><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe801;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#x25a0;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#x266a;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#x26ab;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe055;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe0db;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe802;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe804;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe805;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe80b;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe80f;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe810;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe816;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe81f;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe828;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe82a;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe88c;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe870;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf006;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf0e6;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf118;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf119;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf11a;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe837;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf124;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf18a;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf29c;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#x1f44d;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf2c0;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf299;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8c7;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8ca;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8cb;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf0c5;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe899;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8bf;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf101;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf128;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf10c;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe897;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe874;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8ac;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#x1f44d;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe86d;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe86c;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe815;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe897;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe819;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8cc;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf0e5;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf0fd;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf1d6;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf192;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf157;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8ba;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf27a;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8b5;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8a9;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf12a;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe888;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xe8ab;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf109;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf0ed;</span>' +
        '<span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf0ee;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf25d;</span><span style="float:left;width:16px;height:22px;font-family:fontello;color:#7E7E7E;font-size:16px;line-height:22px;margin:2px 12px;cursor:pointer;">&#xf1f9;</span>' +
        '</div><div style="text-align:center;margin-top:20px;"><button id="_btn_">确认</button></div></div>',
    videoHtml: '<pre contenteditable="false" style="padding:1px;margin:0;" class="k_video_pre"><video controls="true" id="my_video_id" class="k_video_el video-js vjs-default-skin vjs-big-play-centered" src="_$video_url$_" controls preload="auto"   data-setup="{}">' +
        '_$source$_<object id="flash_fallback_1" class="vjs-flash-fallback"  type="application/x-shockwave-flash" data="javascript/video/flowplayer.swf">' +
        '<param name="movie" value="javascript/video/flowplayer.swf" /><param name="allowfullscreen" value="true" />' +
        '<param name="flashvars" value="config={"playlist":["images/confident.jpg", {"url": "_$video_url$_","autoPlay":false,"autoBuffering":true}]}" />' +
        '</object></video></pre>',
    borderForm: '<table style="width:300px;margin-bottom:0;padding-top:6px;" class="form_table k_edit_tools_table" >' +
        '<tr><td style="width:100px"><span style="padding:2px 12px;">边框位置：</span></td><td><span id="k_border_pos" style="display:inline-block;"><span class="_border_pos" v="left" style="border-width: 1px 1px 1px 2px; border-style: dashed dashed dashed solid; border-color: rgb(204, 204, 204) rgb(204, 204, 204) rgb(204, 204, 204) rgb(0, 0, 255); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span><span class="_border_pos" v="top" style="border-width: 2px 1px 1px; border-style: solid dashed dashed; border-color: rgb(0, 0, 255) rgb(204, 204, 204) rgb(204, 204, 204); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span><span class="_border_pos" v="right" style="border-width: 1px 2px 1px 1px; border-style: dashed solid dashed dashed; border-color: rgb(204, 204, 204) rgb(0, 0, 255) rgb(204, 204, 204) rgb(204, 204, 204); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span><span class="_border_pos" v="bottom" style="border-width: 1px 1px 2px; border-style: dashed dashed solid; border-color: rgb(204, 204, 204) rgb(204, 204, 204) rgb(0, 0, 255); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span></span></td></tr>' +
        '<tr><td style="width:100px"><span style="padding:2px 12px;">边框类型：</span></td><td><select id="k_border_style"  style="width:95px;"><option selected="selected" value="solid">实线</option><option value="dotted">点状线</option><option value="dashed">长点状线</option></select></td></tr>' +
        '<tr><td style="width:100px"><span style="padding:2px 12px;">边框大小：</span></td><td><select id="k_border_size"  style="width:95px;"><option value="1px" selected="selected">1px</option><option value="2px">2px</option><option value="3px">3px</option><option value="4px">4px</option><option value="5px">5px</option><option value="6px">6px</option><option value="7px">7px</option><option value="8px">8px</option><option value="9px">9px</option><option value="10px">10px</option></select></td></tr>' +
        '<tr><td style="width:100px"><span style="padding:2px 12px;">边框颜色：</span></td><td><span><i id="k_img_color" unbindcolorev="1" style="border: 1px solid rgb(245, 245, 245); padding-left: 12px; color: rgb(255, 255, 255); background-color: rgb(143, 143, 143); cursor: pointer; opacity: 1;" class="fa fa-brush"></i></span></td></tr>' +
        '<tr><td colspan="2" style="text-align:center;padding-top:6px;"><button id="_cls_btn" style="cursor:pointer;height:24px;line-height:22px;">关闭</button></td></tr></table>',
    paragraphForm: '<table style="width:100%;margin-bottom:0;" class="form_table k_edit_tools_table" >' +
        '<tr><td style="text-align:right;width:65px;" class="k_edit_tools_table_label">缩进：</td><td style="width:130px;"><input autocomplete="off" title="请输入字符数" style="width:100px" placeholder="字符" id="_indent_"  name="indent" type="text"/></td><td ><span style="padding:2px 12px;">边框位置：</span><span id="_border_pos" style="display:inline-block;"><span class="_border_pos" v="left" style="border-width: 1px 1px 1px 2px; border-style: dashed dashed dashed solid; border-color: rgb(204, 204, 204) rgb(204, 204, 204) rgb(204, 204, 204) rgb(0, 0, 255); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span><span class="_border_pos" v="top" style="border-width: 2px 1px 1px; border-style: solid dashed dashed; border-color: rgb(0, 0, 255) rgb(204, 204, 204) rgb(204, 204, 204); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span><span class="_border_pos" v="right" style="border-width: 1px 2px 1px 1px; border-style: dashed solid dashed dashed; border-color: rgb(204, 204, 204) rgb(0, 0, 255) rgb(204, 204, 204) rgb(204, 204, 204); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span><span class="_border_pos" v="bottom" style="border-width: 1px 1px 2px; border-style: dashed dashed solid; border-color: rgb(204, 204, 204) rgb(204, 204, 204) rgb(0, 0, 255); border-image: initial; cursor: pointer; display: inline-block; width: 15px; height: 15px; margin-right: 8px; background-color: transparent;"></span></span></td></tr>' +
        '<tr><td class="k_edit_tools_table_label"  style="text-align:right;">上边距：</td><td><input autocomplete="off"  title="单位像数"  style="width:100px"  placeholder="像素" id="_pdding-top_" name="margin-top" type="text"/></td><td><span style="padding:2px 12px;">边框类型：</span><select id="_border_style"  style="width:66px;"><option selected="selected" value="solid">实线</option><option value="dotted">点状线</option><option  value="dashed">长点状线</option></select></td></tr>' +
        '<tr><td class="k_edit_tools_table_label"  style="text-align:right;">下边距：</td><td><input autocomplete="off"  title="单位像数" style="width:100px"  placeholder="像素" id="_pdding-bottom_" name="margin-bottom" type="text"/></td><td><span style="padding:2px 12px;">边框大小：</span><select id="_border_size"><option value="1px" selected="selected">1px</option><option value="2px">2px</option><option value="3px">3px</option><option value="4px">4px</option><option value="5px">5px</option><option value="6px">6px</option><option value="7px">7px</option><option value="8px">8px</option><option value="9px">9px</option><option value="10px">10px</option></select></td></tr>' +
        '<tr><td class="k_edit_tools_table_label"  style="text-align:right;">左边距：</td><td><input autocomplete="off"  title="单位像数" style="width:100px"  placeholder="像素" id="_padding-left_" name="padding-left" type="text"/></td><td><span style="padding:2px 12px;">边框颜色：</span><span id="_border_color" unbindcolorev="1" style="background-color:#4F4B49;"><i style="border: 1px solid rgb(245, 245, 245); padding-left: 12px;  cursor: pointer;padding-left: 5px ;padding-right:5px;" class="fa fa-brush">' + svgIcon.pen + '</i></span></td></tr>' +
        '<tr><td class="k_edit_tools_table_label"  style="text-align:right;">右边距：</td><td><input autocomplete="off"  title="单位像数" style="width:100px"  placeholder="像素" id="_padding-right_" name="padding-right" type="text"/></td><td><span style="padding:2px 6px 2px 12px;">背景色：</span><span unbindcolorev="1" id="_bg_color"><i   style="border: 1px solid #AAAAAA; padding-left: 2px;cursor: pointer; padding-left: 5px ;padding-right:5px;" class="fa fa-brush">' + svgIcon.pen + '</i></span><span style="padding:2px 6px 2px 20px;">字体颜色：</span><span id="_font_color" unbindcolorev="1"><i style="border: 1px solid #AAAAAA; padding-left: 5px ;padding-right:5px; color: #ffffff; cursor: pointer; opacity: 1;" class="fa fa-brush">' + svgIcon.pen + '</i></span></td></tr>' +
        '<tr><td class="k_edit_tools_table_label"  style="text-align:right;">行高：</td><td colspan="2"><select style="width:100px"  id="_line-height_"  name="line-height" style="width:124px"><option name="line-height" value="1.5">单倍</option><option name="line-height" value="1.8">1.5倍</option><option name="line-height" value="2">双倍</option><option name="line-height" value="2.5">高倍</option><option value="">自定义</option></select><span style="padding:2px 12px;"><input placeholder="像数" type="text" id="txt_line_h" style="width:60px"/></span></td></tr>' +
        '</table>',
    fileForm: "<div><div id='_swith_tool' class='k_box_size' style='line-height:16px;border-bottom:1px solid #666666;height:23px;'><a  class='k_box_size'  style='cursor:pointer;padding:2px 6px;background: rgb(102, 102, 102);color:#fff;' id='_local_upload_'>本地上传</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class='k_box_size' id='_remote_upload_' style='cursor:pointer;padding:2px 6px;'>在线附件</a></div>" +
        "<table style='margin-top:20px;padding-left:30px;width:100%;' id='_local_upload_form'  class='form_table k_edit_tools_table'>" +
        "<tr><td><div id='_file_upload_wrap'></div></td></tr></table>" +
        "<table style='margin-top:20px;padding-left:30px;display:none;' id='_remote_upload_form' class='form_table k_edit_tools_table'>" +
        "<tr><td style='width:55px'>地址：</td><td><input id='_addr_url' autocomplete='off' type='text' style='width:380px'/></td></tr></table>" +        
        "<div style='line-height:30px;padding-left:32px;'>名称：&nbsp;&nbsp;&nbsp;&nbsp;<input autocomplete='off' type='text' id='file_name' style='width:380px;'/></div>" +       
        "<div style='text-align:center;margin-top:16px;height:35px'><button id='_submit_upload_' style='cursor:pointer;'>确认</button></div><div id='_upload_res_msg'></div></div>",
    
    linkForm: "<table style='margin-top:20px' class='form_table k_edit_tools_table'><tr><td style='width:50px'>名称：</td><td><input autocomplete='off' type='text' id='_link_name'  style='width:300px'/></td></tr>" +
        "<tr><td>地址：</td><td><input id='_addr_url' autocomplete='off' type='text' style='width:300px'/></td></tr>" +
        "<tr><td colspan='2'>是否新窗口打开：<input id='_target_' class='k_check_style' checked='checked' type='checkbox' /></td></tr>" +
        "<tr><td colspan='2' style='text-align:center;padding:4px 5px;'><button style='cursor:pointer;' id='okbtn'>确认</button></td></tr></table>",
    linkMenu:'<div><p><span>访问：</span><a id="_op_link" target="blank"></a></p><p id="_del_link">删除链接</p></div>',
    splitForm: "<table style='margin-top:2px' class='form_table k_edit_tools_table'>" +
        "<tr><td style='width:80px;text-align:right;'>颜色：</td><td><input unbindcolorev='' id='_line_color_' style='width:150px' type='text' readonly='readonly'/></td></tr>" +
        "<tr><td style='width:80px;text-align:right;padding: 2px 16px 2px 2px;'>大小：</td><td><select id='_line_size' style='width:150px'><option selected='selected' value='1px'>1px</option><option value='2px'>2px</option><option value='3px'>3px</option><option value='4px'>4px</option><option value='5px'>5px</option><option value='6px'>6px</option><option value='7px'>7px</option><option value='8px'>8px</option><option value='9px'>9px</option><option value='10px'>10px</option></select></td></tr>" +
        "<tr><td style='width:80px;text-align:right;'>类型：</td><td><select  id='_line_style' style='width:150px;padding: 2px 16px 2px 2px;'><option selected='selected' value='solid'>单实线</option><option  value='dotted'>点状</option><option  value='dashed'>长点状</option><option  value='double'>双实线</option></select></td></tr>" +
        "<tr><td style='text-align:left;padding-left:28px;' colspan='2'>上边距：&nbsp;<input autocomplete='off' id='_line_top' type='text' placeholder='px' style='width:50px;padding:0px 2px'/> 下边距：<input id='_line_bottom' type='text' placeholder='px'  style='width:50px;padding:0px 2px'/></td></tr></table>",
    tablePropsForm: "<table class='k_edit_props_form'><tr><td>修饰对象:</td><td>表格<input autocomplete='off' value='1' id='_target_table_1' name='_target_' type='radio' style='margin:0px 4px'/>单元格<input  style='margin:0px 4px'  checked='checked' id='_target_cell_1'  value='0' name='_target_' type='radio'/></td></tr>" +
        "<tr><td  style='text-align:rgiht'>修饰边框:</td><td class='k_edit_border_wrap' id='k_edit_border_wrap'><div  title='上边框' tg='border-top' class='border_top _border_it'></div><div  title='右边框'  tg='border-right' class='border_right _border_it'></div><div  title='下边框' tg='border-bottom' class='border_bottom _border_it'></div><div  title='左边框' tg='border-left'  class='border_left _border_it'></div></td></tr>" +
        "<tr><td  style='text-align:rgiht'>边框大小:</td><td><select id='_border_size_opts_' style='width:50px;padding: 1px 16px 1px 1px;'><option selected='selected' value='1px'>细</option><option value='2px'>中</option><option value='3px'>粗</option></select><div id='_border_size_input' style='height:28px;width:60px;float:right;'></div></td></tr>" +
        "<tr><td  style='text-align:rgiht'>边框类型:</td><td><select id='_border_style_opts_' style='width:110px;padding: 1px 16px 1px 1px;'><option value='solid'>solid</option><option selected='selected' value='dashed'>dashed</option><option value='double'>double</option></select></td></tr>" +
        "<tr><td  style='text-align:right'>颜色：</td><td><div id='_border_color_picker' unbindcolorev='1' title='边框颜色' class='k_box_size _color_picker' style='background-color:#313131; width:20px;border:1px solid #ADA8A3;height:18px;float:left;margin-right:10px;'><i class='fa fa-brush-1'></i></div><div id='_font_color_picker' unbindcolorev='1' title='字体颜色' class='k_box_size _color_picker' style='width:20px;border:1px solid #ADA8A3;height:18px;float:left;margin-right:10px;'><i class='fa fa-brush-1'></i></div><div id='_fill_color_picker' unbindcolorev='1' title='填充颜色' class='k_box_size _color_picker' style='float:left;width:20px;border:1px solid #ADA8A3;height:18px;margin-right:10px;'><i class='fa fa-brush-1'></i></div></td></tr>" +
        "<tr><td  style='text-align:right'>对齐：</td><td id='_table_align'><div title='左对齐' class='k_box_size h_left _h' ><i style='position:relative;bottom:2px;' class='fa fa-align-left'></i></div><div  title='居中对齐' class='k_box_size h_center  _h'><i style='position:relative;bottom:2px;left:0px' class='fa fa-align-center'></i></div><div title='右对齐' class='k_box_size h_right  _h' ><i style='position:relative;bottom:2px;left:3px;' class='fa  fa-align-right'></i></div><div title='顶部对齐' class='k_box_size v_top _v' ><i style='position:relative;bottom:8px;left:2px;' class='fa  fa-menu-1'></i></div><div title='重直居中' class='k_box_size v_middle _v' ><i style='position:relative;bottom:3px;left:2px;' class='fa  fa-menu-1'></i></div><div title='底部对齐' class='k_box_size v_bottom _v' ><i style='position:relative;bottom:0px;left:2px;' class='fa  fa-menu-1'></i></div></td></tr>" + "<tr class='_insert_op_tr edit_prop_tr_hover' id='_insert_op_tr'><td colspan='2' class='k_edit_delete_op_tr'><div style='text-align:center;line-height:20px;'>插入<i style='float:right;font-size:16px;line-height:22px;' class='fa fa-angle-double-right'></i></div></td></tr>" +
        "<tr class='_delete_op_tr edit_prop_tr_hover' id='_delete_op_tr'><td colspan='2' class='k_edit_delete_op_tr'><div style='text-align:center;line-height:20px;'>删除<i style='float:right;font-size:16px;line-height:22px;' class='fa fa-angle-double-right'></i></div></td></tr>" +
        "<tr class='edit_prop_tr_hover' id='_graph_td_' ><td colspan='2' style='text-align:center;cursor:pointer;line-height:20px;'><i class='fa fa-doc-text' style='margin-right:4px'></i><a style='cursor: pointer;'>段落设置</a></td></tr>" +
        "<tr class='edit_prop_tr_hover' id='_split_merge_td_' style='display:none;'><td colspan='2' style='text-align:center;cursor:pointer;line-height:20px;'><i class='fa fa-columns' style='margin-right:4px'></i><a style='cursor: pointer;'>合并</a></td></tr>" +
        "</table>",
    imageForm: "<div><div id='_swith_tool' class='k_box_size' style='line-height:16px;border-bottom:1px solid #666666;height:23px;'><a  class='k_box_size'  style='cursor:pointer;padding:2px 6px;background: rgb(102, 102, 102);color:#fff;' id='_local_upload_'>本地上传</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class='k_box_size' id='_remote_upload_' style='cursor:pointer;padding:2px 6px;'>网络图片</a></div>" +
        "<table style='margin-top:20px;padding-left:30px;width:100%;' id='_local_upload_form'  class='form_table k_edit_tools_table'>" +
        "<tr><td><div id='_file_upload_wrap'></div></td></tr></table>" +
        "<table style='margin-top:20px;padding-left:30px;display:none;' id='_remote_upload_form' class='form_table k_edit_tools_table'>" +
        "<tr><td style='width:55px'>地址：</td><td><input id='_addr_url' autocomplete='off' type='text' style='width:380px'/></td></tr></table>" +
        "<div style='line-height:30px;padding-left:35px;padding-top:5px;'>边距：&nbsp;&nbsp;&nbsp;&nbsp;上：<input autocomplete='off' id='_top_k_padding' value='0' type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;" +
        "下：<input id='_bottom_k_padding' autocomplete='off' value='0'  type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;左：<input value='0' autocomplete='off' id='_left_k_padding' type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;" +
        "右：<input id='_right_k_padding' autocomplete='off' value='0'  type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;</div>" +
        "<div style='line-height:30px;padding-left:35px;'>高度：&nbsp;&nbsp;&nbsp;&nbsp;<input autocomplete='off' type='text' id='_img_height' style='width:80px;padding:1px 2px;'/>&nbsp;&nbsp;&nbsp;&nbsp;宽度：<input id='_img_width' type='text' style='width:80px;padding:1px 2px;'/></div>" +
        "<div style='line-height:30px;padding-left:35px;padding-top:10px;' id='k_edit_img_layout' class='clearfix'><div style='float:left;'>位置：</div><a v='left' title='文字右环绕' class='k_edit_img_pos k_edit_img_pos_left'></a><a v='center' title='无环绕独占一行' class='k_edit_img_pos k_edit_img_pos_center'></a><a v='right' title='文字左环绕' class='k_edit_img_pos k_edit_img_pos_right'></a><a v='inner' title='行内图片' class='k_edit_img_pos k_edit_img_pos_innser pos_actived'></a><span style='color:red;margin-left:12px;display:block;float:left;'>请注意选择图片位置！</span><input type='hidden' id='_img_pos' value='inner'/></div>" +
        "<div style='line-height:30px;padding-left:35px;padding-top:10px;' class='clearfix'><div style='float:left;'>跳转地址：</div><input id='_href_' autocomplete='off' type='text' placeholder='点击图片打开的连接地址' style='width:380px'/></div>" +
        "<div style='text-align:center;margin-top:16px;height:35px'><button id='_submit_upload_' style='cursor:pointer;'>确认</button></div><div id='_upload_res_msg'></div></div>",
    imgEditForm:'<div><div style="line-height:30px;padding-left:35px;padding-top:15px;">边距：&nbsp;&nbsp;&nbsp;&nbsp;上：<input autocomplete="off" id="_top_k_padding" value="0" type="text" style="width:50px;padding:1px 2px;">&nbsp;&nbsp;'
        +'下：<input id="_bottom_k_padding" autocomplete="off" value="0" type="text" style="width:50px;padding:1px 2px;">&nbsp;&nbsp;左：<input value="0" autocomplete="off" id="_left_k_padding" type="text" style="width:50px;padding:1px 2px;">&nbsp;&nbsp;'
        +'右：<input id="_right_k_padding" autocomplete="off" value="0" type="text" style="width:50px;padding:1px 2px;">&nbsp;&nbsp;</div><div style="line-height:30px;padding-left:35px;">'
        +'高度：&nbsp;&nbsp;&nbsp;&nbsp;<input autocomplete="off" type="text" id="_img_height" style="width:80px;padding:1px 2px;">&nbsp;&nbsp;&nbsp;&nbsp;宽度：<input id="_img_width" type="text" style="width:80px;padding:1px 2px;"></div>'
        +'<div style="text-align:center;margin-top:16px;height:35px"><button id="_submit_upload_" style="cursor:pointer;">确认</button></div></div>',
    videoForm: "<div><div class='k_box_size' style='line-height:16px;border-bottom:1px solid #666666;height:23px;'><a  class='k_box_size'  style='cursor:pointer;padding:2px 6px;' id='_local_upload_'>本地上传</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class='k_box_size' id='_remote_upload_' style='cursor:pointer;padding:2px 6px;'>网络视频</a></div>" +
        "<table style='margin-top:20px;padding-left:30px;' id='_local_upload_form'  class='form_table k_edit_tools_table'>" +
        "<tr><td colspan='2' id='_video_upload_wrap'></td></tr></table>" +
        "<table style='margin-top:20px;padding-left:30px;' id='_remote_upload_form' class='form_table k_edit_tools_table'>" +
        "<tr><td style='width:55px'>地址：</td><td><input id='_addr_video' type='text' autocomplete='off' style='width:380px'/></td></tr></table>" +
        "<div style='line-height:30px;padding-left:35px;padding-top:0px;'>边距：&nbsp;&nbsp;&nbsp;&nbsp;上：<input autocomplete='off' id='_top_v_padding' value='4' type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;" +
        "下：<input id='_bottom_v_padding' autocomplete='off' value='4'  type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;左：<input autocomplete='off' value='2' id='_left_v_padding' type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;" +
        "右：<input id='_right_v_padding' autocomplete='off' value='2'  type='text' style='width:50px;padding:1px 2px;'/>&nbsp;&nbsp;</div>" +
        "<div style='line-height:30px;padding-left:35px;'>高度：&nbsp;&nbsp;&nbsp;&nbsp;<input type='text' id='_video_height' autocomplete='off' value='360' style='width:80px;padding:1px 2px;'/>&nbsp;&nbsp;&nbsp;&nbsp;宽度：<input value='580' id='_video_width' type='text' style='width:80px;padding:1px 2px;'/></div>" +
        "<div style='line-height:30px;padding-left:35px;'><span title='以视频文件名结束的地址,如:xx.mp4' style='display:none;' id='_is_real_video'>是否纯视频地址:&nbsp;&nbsp;&nbsp;&nbsp;<label class='k_checkbox_label k_checkbox_anim'><input type='checkbox' id='_video_is' value='360' style='width:80px;padding:1px 2px;'/><i class='k_checkbox_i'></i></label></span></span><span id='_is_loop_play'>是否循环播放:&nbsp;&nbsp;&nbsp;&nbsp;<label class='k_checkbox_label k_checkbox_anim'><input type='checkbox' id='_video_repeat' value='360' style='width:80px;padding:1px 2px;'/><i class='k_checkbox_i'></i></label></span></div>" +
        "<div style='text-align:center;margin-top:16px;height:35px'><button id='_submit_upload_' style='cursor:pointer;'>确认</button></div><div id='_upload_res_msg'></div></div>",
    closedForm: "<table style='margin-top:20px' class='form_table k_edit_tools_table'><tr><td style='width:150px;text-align:right'>向下折叠：</td><td style='padding-right:30px'><select style='padding-right:5px;padding-left:5px;margin-right:6px;' id='_section_c'><option selected='selected' value='1'>1</option><option value='2'>2</option><option value='3'>3</option><option value='4'>4</option><option value='5'>5</option></select>段落</td></tr>" +
        "<tr><td style='width:150px;text-align:right'>初始状态： </td><td style='padding-right:30px'><label class='k_radio_label k_radio_anim'><input autocomplete='off' type='radio' name='_status' value='1' checked='checked'><i class='k_radio_i'></i>展开</label><label class='k_radio_label k_radio_anim'><input type='radio' name='_status' value='0'><i class='k_radio_i'></i>收起</label></td></tr>" +
        "<tr><td colspan='2' style='text-align:center;'><button style='cursor:pointer;'>确认</button></td></tr></table>",
    codeForm: '<div style="width:100%;height:100%;position:relative;" class="k_box_size"><div id="toolbar" style="height:25px;width:100%;position:absolute;top:0;z-index:2;border:1px dashed #ccc;">'
        + '<span style="float:left;margin:0 20px;">代码修饰：</span><span class="font_css" id="bold"  tabindex="0" title="加粗代码" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;font-weight: bold;text-align:center;line-height:20px;">B</span>'
        + '<span id="normal"  class="font_css"   title="取消加粗" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;">B</span>'
        + '<span id="red" color="#FF0005"  class="font_css"  title="字体红色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:red;">A</span>'
        + '<span id="greed" color="#0FE000"  class="font_css"  title="绿色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#0FE000;">A</span>'
        + '<span id="blank" color="#666666"  class="font_css"  title="淡黑色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#666666;">A</span>'
        + '<span id="blank1" color="#000000"  class="font_css"  title="黑色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#666666;">A</span>'
        + '<span id="blinkred" color="#FF00D1"  class="font_css"  title="粉红色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#FF00D1;">A</span>'
        + '<span id="yello" color="#FFD600"  class="font_css"  title="黄色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#FFD600;">A</span>'
        + '<span id="blue" color="#0089FF"  class="font_css"  title="蓝色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#0089FF;">A</span>'
        + '<span id="bluelingth" color="#A5A5FF"  class="font_css"  title="淡蓝色" tabindex="0" style="display:block;width:20px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#A5A5FF;">A</span>'
        + '<span id="fontSize" tabindex="0" style="display:block;height:24px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;">字号：<select tabindex="0"><option value="14">14px</option><option value="16">16px</option><option value="18">18px</option></select></span>'
        + '<span id="isClearBackground" tabindex="0" style="display:block;height:24px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:25px;line-height:20px;text-align:center;">是否保留复制携带的背景色：<select tabindex="0"><option value="0">否</option><option value="1">是</option></select></span>'
        + '<span id="_clr_btn_" class="_btn_clr"  title="清空" tabindex="0" style="display:block;width:60px;height:20px;float:left;margin:0 2px;margin-top:3px;cursor:pointer;margin-left:20px;line-height:20px;text-align:center;color:#0089FF;">清空</span>'
        + '</div><div class="k_box_size" style="width:100%;height:100%;position:relative;z-index:1;border:1px dashed #ccc;border-bottom:35px solid #fff;border-top:28px solid #fff;"><pre id="input_txt" class="k_box_size" contenteditable="true" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false" style="width:100%;height:100%;padding:6px 10px;overflow:auto;"><div id="k_code_input" class="k_code_input" style="position:relative;width:100%;height:100%;min-width:100%;min-height:100%;box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;"><div>\u200B</div><div>\u200B</div></div></pre></div>'
        + '<div class="k_box_size" style="padding-top:4px;position:absolute;width:100%;height:35px;bottom:0;z-index:2;text-align:center;border-top:1px dashed #ccc;"><button>确认</button></div></div>',    
    map: {
        windowSize: { width: 600, height: 500 },
        insertSize: { height: 500, width: '100%' },
        page: 'map.html',
    },
    imgPos:""
};
let userCfg = {};
if ($B.config && $B.config.editor) {
    userCfg = $B.config.editor;
}
$B["extendObjectFn"](editCfg, userCfg);
var defaultOpts = {
    needTools: true,
    mutilPage: true
};
/**
 * 富文本Class定义，
 * 封装富文本输入框事件、选区相关API
 * 定义extend注册函数，其他功能模块通过extend实现注册
 * by kevin.huang
 * ***/
class Keditor extends $B.BaseControl {
    constructor(elObj, opts) {
        super();
        this.DPI = UTILS.getDPI();
        console.log("dpi "+this.DPI);       
        this.opts = $B.extendObjectFn(true, {}, defaultOpts, opts);
        this.debug = this.opts.debug;
        super.setElObj(elObj);
        $B.DomUtils.addClass(this.elObj, "k_edit_main k_box_size");
        let contents = this.elObj.innerHTML;
        this.elObj.innerHTML = "";        
        this.$mainWrap = $B.DomUtils.createEl("<div  class='k_edit_input_wrap k_box_size' style='overflow: hidden; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;background:#F3F4F5;'></div>");
        var _this = this;
        this.colorIns = new $B.Color(undefined, {
            mouseleaveHide: true,
            onChange: function (hex, opacity) {
                if (_this.colorIns._callFnKey) {
                    let colorCallFN = "color_" + _this.colorIns._callFnKey;
                    if (_this[colorCallFN]) {
                        _this[colorCallFN].call(this, hex, opacity);
                    }
                }
            },
            onHideFn: function (ins) {
                _this.clearSelectionColor();            
            }
        });       
        if (this.opts.needTools) {
            this.toolIns = new KeditTools(this);
            let h = this.toolIns.getHeight() + 2;
            $B.DomUtils.css(this.$mainWrap, { "border-top": h + "px solid #fff" });
        }        
        let $pageEl = this.createDocPage(true);
        if (this.opts.mutilPage) {
            $B.Dom.css(this.$mainWrap, { "border-bottom": "32px solid #F3F4F5", "overflow": "auto"});
            this.initMutilPage($pageEl);
            setTimeout(()=>{
                this.insertPage();
                this.insertPage();
            },0);
            this.setInputElVar(this.$pageWap.firstChild);
        } else {
            $B.Dom.append(this.$mainWrap, $pageEl);
            this.$pageWap = $pageEl;
            this.setInputElVar(this.$pageWap);
        }       
        this.bindInputeEvents(this.$input);
        this.cssEls = [];//需要修饰的元素
        this.cssPEls = [];  //段落

        setTimeout(() => {
            this.bindFocusEv(this.colorIns.elObj);
        }, 10);        
        contents = this.clearHtmlStr(contents);
        if (contents !== "") {
            this.$input.innerHTML = contents;
        }
        $B.DomUtils.prepend(this.elObj, this.$mainWrap);

        $B.DomUtils.mouseup(document, (e) => {
            if (this.isUserMouseDown) {
                if (this.tableIns.isSelectedTds()) {
                    this.tableIns.cancelMutilSelect();
                } else {
                    this.mouseup(e);
                }
            }
        });
        this.tableIns = new Table(this);
        if (navigator.userAgent.indexOf("Firefox") > 0) {
            document.designMode = "on";
            document.execCommand('enableObjectResizing', false, 'false');
            document.designMode = "off";
        }

        var isReqFrame = false;
        var resizeEvent = () => {
            if (!isReqFrame) {
                isReqFrame = true;
                requestAnimationFrame(() => {
                    isReqFrame = false;
                    let headH;
                    if (this.opts.needTools) {
                        headH = this.toolIns.getHeight() + 2;
                        let old = parseFloat(this.$mainWrap.style.borderTopWidth.replace("px", ""));
                        if (headH !== old) {
                            $B.DomUtils.css(this.$mainWrap, { "border-top": headH + "px solid #fff" });
                        }
                    }
                    if (this.onResizingFn) {
                        this.onResizingFn(headH);
                    }
                });
            }
        };
        $B.DomUtils.resize(window, resizeEvent, 100);
        this.ResizeIns = new $B.Resize({
            target: undefined,
            dragStart: function (args) {
            },
            onDrag: function (args) {
                console.log("resizing ", args);
            },
            dragEnd: function (args) {
                console.log("resize end ", args);
            }
        });
        this.ResizeIns.setStyle({
            "background": "#0C9CE5",
            "width": 6,
            "height": 6
        }, {
            "border": "1px dashed #0C9CE5"
        });
        setTimeout(() => {
            this.URDOINS = new URDO(this);
        }, 10);
    }
    setInputElVar($pageEl){
        this.$input = this.getPageInputEl($pageEl); 
    }
    getPageInputEl($pageEl){
        if (this.opts.mutilPage) {//多页模式
            let $0 = this.getPageInputWrap($pageEl);
            return $B.Dom.children($0, "._input_field")[0];
        }
        return $B.Dom.children($pageEl, "._input_field")[0];
    }
    getPageInputWrap($pageEl){
        let $0 = $B.Dom.children($pageEl,".pg_input_wap")[0];
        return $0;
    }   
    getColorIns(eventKey, onChange) {
        let colorCallFN = "color_" + eventKey;
        this[colorCallFN] = onChange;
        return this.colorIns;
    }
    /**
     * 处理入口
     * fn：处理函数的名称，params参数，eventEl触发处理的元素
     * **/
    execute(fn, params, eventEl) {
        if (typeof this[fn] === "function") {
            let go = this.beforeExecute(fn, params, eventEl);
            if (go) {
                if (fn !== "paintBrushFn" && fn !== "clearFn" && fn !== "eraserFn" && fn !== "insertTableFn") {
                    this.makeUndoData(fn, params);
                }
                this[fn](params, eventEl);
                let timer = 1;
                if (fn === "backgroundColorFn" || fn === "fontColorFn" || fn === "pcolorFn" || fn === "pbackground") {
                    timer = 1000;
                }
                this.putUndoData(timer);
            }
            this.afterExecute(fn, params, eventEl);
        } else {
            if (fn === "undoFn" || fn === "redoFn") {
                this.URDOINS[fn]();//执行撤销回退
            }
        }
    }
    makeUndoData(fn, params) {
        this.URDOINS.makeUndo(fn, params);
    }
    putUndoData(time) {
        if (!time) {
            time = 1;
        }
        clearTimeout(this.putUndoTimer);
        this.putUndoTimer = setTimeout(() => {
            this.URDOINS.putCurUndo();
            this.URDOINS.clearRedoRec();
            this.clearUndoingData();
        }, time);
    }
    /**
     * isForce是否强制生成一个新的undo记录
     * **/
    makePutUndoImd(isForce) {
        if (isForce) {
            this.clearUndoingData();
        }
        this.makeUndoData();
        this.putUndoData(1);
    }
    clearUndoingData() {
        this.URDOINS.undoData = undefined;
    }
    /**
     * 绑定输入域事件
     * **/
    bindInputeEvents($input) {
        if (!this.inputEvents) {
            this.inputEvents = {
                mousedown: (e) => {
                    UTILS.stopDefaultctxMenu();
                    let r = this.mousedown(e);
                    if (typeof r !== "undefined") {
                        return r;
                    }
                },
                mouseup: (e) => {
                    if (this.tableIns.isSelectedTds()) {
                        this.tableIns.cancelMutilSelect();
                    } else {
                        let r = this.mouseup(e);
                        if (typeof r !== "undefined") {
                            return r;
                        }
                    }
                },
                keydown: (e) => {
                    let r = this.keydown(e);
                    if (typeof r !== "undefined") {
                        return r;
                    }
                },
                keyup: (e) => {
                    let r = this.keyup(e);
                    if (typeof r !== "undefined") {
                        return r;
                    }
                },
                mouseleave: (e) => {
                    this.mouseleave(e);
                },
                paste: (e) => {
                    this.paste(e);
                    if (typeof r !== "undefined") {
                        return r;
                    }
                },
                focus: (e) => {
                    if (this.tableIns.isSelectedTds()) {
                        let el = e.target;
                        this._fixFocusOnMonseEvent(el);
                    }
                }
            };
        }
        $B.DomUtils.bind($input, this.inputEvents);
        if (!this.wrapEvents) {
            this.wrapEvents = {
                mousemove: (e) => {
                    if (this.BrushingCSS) {
                        this.brushingMoving(e);
                    }
                }
            };
        }
        if (!this.scrollListner) {
            let isReqFrame = false;
            this.scrollListner = (e) => {
                if (!isReqFrame) {
                    isReqFrame = true;
                    let el = e.target;
                    requestAnimationFrame(() => {
                        if (!this._scringprs) {
                            this._scringprs = {
                                top: el.scrollTop,
                                left: el.scrollLeft
                            };
                        }
                        let diff1 = Math.abs(el.scrollTop - this._scringprs.top);
                        let diff2 = Math.abs(el.scrollLeft - this._scringprs.left);
                        if (diff1 > 5 || diff2 > 5) {
                            this.hidePanel();
                        }
                        this._scringClrTimer = setTimeout(() => {
                            this._scringprs = undefined;
                        }, 800);
                        if (this.onScrolling) {
                            this.onScrolling(e)
                        }
                        isReqFrame = false;
                    });
                }
            };
        }
        if (this.opts.mutilPage) {
            $B.DomUtils.scroll(this.$pageWap, this.scrollListner);
        } else {
            this.wrapEvents["scroll"] = this.scrollListner;
        }
        $B.DomUtils.bind($input.parentNode, this.wrapEvents);
    }
    /**
     * 按下键处理，对delete事件做删除前处理，防止出现空标签，无span标签场景
     * 对回车事件做处理，修正浏览器默认处理
     * **/
    keydown(e) {
        if (e.keyCode === 9) {
            this.isTabkey = true;
            clearTimeout(this._tabkeyTimer);
            this._tabkeyTimer = setTimeout(() => {
                this.isTabkey = undefined;
            }, 500);
            return false;
        }
        var isDeleted = e.keyCode === 8 || e.keyCode === 46;
        if (isDeleted) {
            //提取在删除区域内的td元素，为td元素做修复处理
            let focusEl = this._getDomRange(true);//先获取当前鼠标所在的元素           
            let isOnlyEl = !focusEl.nextSibling && !focusEl.previousSibling;
            if (isOnlyEl) { //只有一个元素
                let $pel = this._getPelByChild(focusEl);
                if (!$pel.previousSibling) {
                    if (focusEl.innerText === "\u200B") { //第一行不允许删除
                        return false;
                    }
                }
            }
            this.focusPElement = this._getPelByChild(focusEl);//当前focus段落
            this.makeUndoData();
            this.putUndoData(666);
        } else if (e.keyCode === 13) {//回车
            this.focusElement = this._getDomRange(true);//先获取当前鼠标所在的元素 
            if (!this.enterKeyDownp) {
                this.enterKeyDownp = this._getPelByChild(this.focusElement);
            }
            this.listStyle = this.anyliscList(this.focusElement);
        }
    }
    /**
     * 放开按键处理
     * **/
    keyup(e) {
        if (this.isTabkey) {
            this.convertTabKey(e);
            return false;
        }
        clearTimeout(this._savingRegionTimer);
        this._savingRegionTimer = setTimeout(() => {
            this.saveRegion();
        }, 500);
        //确保光标不在\u200b前面  
        if (e.keyCode >= 37 && e.keyCode <= 40) {
            this.checkCursorPos();
            return true;
        }
        var isDeleted = e.keyCode === 8 || e.keyCode === 46;
        let goCheckSeq = true;
        if (isDeleted) {
            if (this.focusPElement) {
                if (this.focusPElement.firstChild.tagName === "BR") {
                    if (this.focusPElement.previousSibling) {
                        this.move2end(this.focusPElement.previousSibling);
                        $B.DomUtils.remove(this.focusPElement);
                    } else {
                        let $br = this.focusPElement.firstChild;
                        let $span = this.createSpanEl();
                        $B.DomUtils.append(this.focusPElement, $span);
                        this.focusPElement.removeChild($br);
                        this.move2end($span);
                    }
                }
                this.focusPElement = undefined;
            }
        } else if (e.keyCode === 13) {//回车
            goCheckSeq = false;
            this.onEnterAfter(e);
        }
        if (goCheckSeq) {
            this.keyupSEQ(e, isDeleted);
        }

    }
    checkCursorPos() {
        console.log("checkCursorPos>>>");
        clearTimeout(this.checkCursorTimer);
        this.checkCursorTimer = setTimeout(() => {
            let rgi = this._getDomRange();
            let start = rgi.startOffset;
            let txtNode = rgi.endContainer;
            let txt = txtNode.nodeValue;
            if (txt[0] === "\u200b" && start === 0) {
                this.setRegion(txtNode, txtNode, 1, 1);
                this.saveRegion();
            }
        }, 222);
    }
    keyupSEQ(e, isDeleted) {
        clearTimeout(this.keyupSEQTimer);
        this.keyupSEQTimer = setTimeout(() => {
            if (isDeleted) {
                let focusEl = this._getDomRange(true);
                let focusPElement = this._getPelByChild(focusEl);//当前focus段落
                let math = this.anyliscList(focusPElement);
                if (math) {
                    math.usePrs = true;
                    this.updateListSeq(focusPElement.nextSibling, math);
                }
            }
        }, 500);
    }
    convertTabKey(e) {
        let rgi = this._getDomRange();
        if (rgi.collapsed) {
            let txtNode = rgi.endContainer;
            let $prt = txtNode.parentNode;
            let start = rgi.startOffset;
            if (e.shiftKey && start === 0) {
                return;
            }
            start = this.addTabspace(txtNode, start, $prt, e.shiftKey);
            this.setRegion($prt.firstChild, $prt.firstChild, start, start);
            this.saveRegion();
        } else { //批量划选
            if (this.cssPEls.length === 0) {
                this.getCssEls(true);
            }
            this.loopPelCssEls(($p) => {
                let $s = $p.firstChild;
                if ($s.nodeName === "SPAN") {
                    if (!$B.Dom.attr($s, "contenteditable")) {
                        console.log($s, $s.innerHTML);
                        this.addTabspace($s.firstChild, 0, $s, e.shiftKey);
                    }
                }
            });
        }
    }
    addTabspace(txtNode, start, $prt, shiftKey) {
        let txt = txtNode.nodeValue;
        let news = [];
        if (shiftKey) {
            news = Array.from(txt);
            let i = 0;
            let shiftCount = 0;
            while (true) {
                if (news.length > 0) {
                    if (news[0] === "\u200b") {
                        if (news.length > 1) {
                            news[0] = news[1];
                            news[1] = "\u200b";
                        }
                    }
                    if (/\s/.test(news[0])) {
                        news.shift();
                        shiftCount++;
                    }
                }
                i++;
                if (i > 4 || shiftCount == 2) {
                    break;
                }
            }
            start = start - shiftCount;
            if (start < 0) {
                start = 0;
            }
        } else {
            if (start === 0 || (txt[0] === "\u200b" && start === 1)) {
                news.push("&nbsp;&nbsp;");
                news.push(txt);
            } else if (start === txt.length) {
                news.push(txt);
                news.push("&nbsp;&nbsp;");
            } else {
                for (let i = 0; i < txt.length; i++) {
                    news.push(txt[i]);
                    if ((i + 1) === start) {
                        news.push("&nbsp;&nbsp;");
                    }
                }
            }
            start = start + 2;
        }
        let newTxt = news.join("");
        if (newTxt === "") {
            newTxt = "\u200b";
        }
        $prt.innerHTML = newTxt;
        return start;
    }
    /**
    * 回车处理
    * ***/
    onEnterAfter(e) {
        var $startP = this.enterKeyDownp;
        this.enterKeyDownp = undefined;
        var ancEl = this.getFocusEle();
        var $up = ancEl.parentNode;
        var $p = $startP.nextSibling;
        let plist = [];
        while ($p) {
            let id = $B.generateDateUUID();
            $p.id = id;
            UTILS.removeBr($p);
            let childs = $p.children;
            if (childs.length > 0) {
                for (let i = 0; i < childs.length; i++) {
                    UTILS.removeBr(childs[i]);
                    if (childs[i].children.length === 0 && childs[i].innerText === "") {
                        childs[i].innerText = "\u200b";
                    }
                    this.loopUpdateId(childs[i]);
                }
            } else {
                $B.Dom.append($p, UTILS.createSpanEl());
            }
            plist.push($p);
            if ($p === $up) {
                break;
            }
            $p = $p.nextSibling;
        }
        if (this.listStyle) {
            let listStyle = this.listStyle;
            this.listStyle = undefined;
            //格式化一下序列           
            if (listStyle.idxText) {
                let $prep = listStyle.prePel;
                let $s = $prep.firstChild;
                let txt = $s.innerText.replaceAll("\u200b", "");
                txt = txt.replace(listStyle.idxText, "\u200b");
                $s.innerText = txt;
                $s = UTILS.createSpanEl();
                $s.innerText = "\u200b" + listStyle.idxText;
                $B.Dom.prepend(listStyle.prePel, $s);
            }
            //新行序列
            let mats = listStyle.nextIdx.match(/\d+/);
            let idx = parseInt(mats[0]);
            for (let i = 0; i < plist.length; i++) {
                $p = plist[i];
                let $s = UTILS.createSpanEl();
                $s.innerText = "\u200b" + listStyle.nextIdx.replace(/\d+/, idx);
                $B.Dom.prepend($p, $s);
                idx++;
            }
            if ($p.nextSibling) {
                this.updateListSeq($p.nextSibling, listStyle);
            }
        }
        this.focusElement = undefined;
        this.move2end($p);
        this.saveRegion();
    }
    /**
     * 清空划选的元素
     * **/
    clearCssEls() {
        this.cssEls = [];
        this.cssPEls = [];
    }
    _fixFocusOnMonseEvent(el) {
        let isRoot = $B.DomUtils.hasClass(el, "k_edit_input");
        if (isRoot) {
            el = el.lastChild;
        }
        if ($B.DomUtils.hasClass(el, "p_element")) { //嵌套表格所在行
            //console.log("on mouse down focus p");
            if (el.firstChild.nodeName === "TABLE") {
                this.skipMouseUP = true;
                setTimeout(() => {
                    this.skipMouseUP = undefined;
                    if (this.tableIns.isSelectedTds()) {//不需要focus元素
                        this.clearDomSelected();
                    } else {
                        this.tableIns.focusTable(el.firstChild);
                        this.reactiveTools();
                    }
                }, 1);
                return;
            } else if (isRoot) {
                this.skipMouseUP = true;
                setTimeout(() => {
                    this.skipMouseUP = undefined;
                    this.move2end(el.lastChild);
                    this.reactiveTools();
                }, 1);
                return;
            } else {
                this.move2end(el.lastChild);
            }
        }
    }
    isLinkAEl(el) {
        let isLinkClick = false;
        if (el.nodeName === "A") {
            isLinkClick = true;
        } else if ($B.Dom.hasClass(el, "_hyper_link")) {
            isLinkClick = true;
        }
        return isLinkClick;
    }
    isImgEl(el) {
        let ret = false;
        if (el.nodeName === "IMG") {
            ret = true;
        } else if ($B.Dom.hasClass(el, "_img_link")) {
            ret = true;
        }
        return ret;
    }
    hideAll() {
        this.ResizeIns.unbind();
        this.hidePanel();
        this.hidenLinkMenu();
        this.hideCtxMenu();
        this.hidenImgMenu();
    }
    /**
     * 按下鼠标左键处理，触发工具栏的监听
     * **/
    mousedown(e) {
        let el = e.target;
        this.hideAll();
        //多页开存在这个功能
        if (this.onClickActivedFN) {
            this.onClickActivedFN(e);
        }
        let go = !this.isLinkAEl(el);
        if (go) {
            go = !this.isImgEl(el);
        } else {
            return false;
        }
        if (go) {
            //如果是表格内点击则不触发clearSelected
            let isTableFrire = false;
            this._fixFocusOnMonseEvent(el);
            let helper = 0;
            while (helper <= 6 && el) {
                if (el.nodeName === "TD") {
                    isTableFrire = true;
                    break;
                }
                el = el.parentNode;
                helper++;
            }
            if (!isTableFrire) {
                this.tableIns.clearSelected(true);
            }
            this.unactivedLinePELS();
            this.clearCssEls();
            this.isUserMouseDown = true;
            if (this.toolIns && typeof this.toolIns.onEditorMouseDown === "function") {
                setTimeout(() => {
                    this.toolIns.onEditorMouseDown();
                }, 1);
            }
            this.isTableFrire = isTableFrire;
            setTimeout(() => {
                this.isTableFrire = undefined;
            }, 500);
        }
    }
    /**
     * 放开按键处理
     * **/
    mouseup(e) {
        if (this.BrushingCSS) {
            this.exeBrushing2el(this.BrushingCSS);
        }
        this.callOffBrush();
        let el = e.target;
        let skip = this.isLinkAEl(el);
        if (skip) {
            this.setRegionByEl(el);
            //弹出链接对话框
            this.showLinkMenu(el);
            return false;
        }
        skip = this.isImgEl(el);
        if (skip) {
            this.showImgMenu(el, e);
            return false;
        }
        if (!skip) {
            if (!e._e._skipDefault && !this.tableIns.dragging) {
                this.isUserMouseDown = false;
                if ($B.DomUtils.hasClass(e.target, "k_edit_td_wap")) {
                    this.move2end(e.target.firstChild.firstChild);
                } else {
                    this.saveRegion();
                }
                setTimeout(() => {
                    this.reactiveTools();
                }, 1);
                if (e.which === 3 && !this.isTableFrire) {
                    this.showCtxMenu({ left: e.pageX + 5, top: e.pageY + 10 });
                }
            }
        }
    }
    brushingMoving(e) {
        if (!this.$movingBrushMouseEl) {
            this.$movingBrushMouseEl = $B.Dom.createEl('<div style=cursor:pointer;position:absolute;width:16px;height:16px;display:none;"><i class="fa fa-brush" style="color:#34B72C;font-size:12px"></i></div>');
            $B.Dom.append(document.body, this.$movingBrushMouseEl);
        }
        this.$movingBrushMouseEl.style.display = "";
        this.$movingBrushMouseEl.style.top = (e.pageY + 3) + "px";
        this.$movingBrushMouseEl.style.left = e.pageX + "px";
    }
    reactiveTools(cssMap) {
        if (this.toolIns && this.toolIns.reactiveUI) {
            if (!cssMap) {
                cssMap = this.extractCss();
            }
            this.toolIns.reactiveUI(cssMap);
        }
    }
    mouseleave(e) {
        //console.log(">>>>>>>>>>",e);
    }
    paste(e) {

    }
    scroll(e) {
        this.hidePanel();
    }
    hidePanel() {
        this.tableIns.hidePanel();
        if (this.toolIns) {
            this.toolIns.hidePanel();
        }
        this.hideCtxMenu();
    }
    /**
     * 绑定鼠标focus事件
     * **/
    bindFocusEv($el) {
        if ($el.tagName !== "IFRAME") {
            if (!this.onFocusFn) {
                this.onFocusFn = (e) => {
                    this.rebuildRegion();
                    return false;
                };
            }
            $B.DomUtils.attribute($el, { "tabindex": "0" });
            $B.DomUtils.focus($el, this.onFocusFn);
            let childs = $el.children;
            for (let i = 0; i < childs.length; i++) {
                this.bindFocusEv(childs[i]);
            }
        }
    }
    /**
     * 获取焦点所在元素
     * isPel是否获取到段落元素
     * **/
    getFocusEle(isPel) {
        var selection = this._getSelection();
        if (selection) {
            var ancNode = selection.anchorNode;
            if (ancNode.nodeType === 3) {
                ancNode = ancNode.parentNode;
            }
            if (!$B.DomUtils.hasClass(ancNode, "p_span")) {
                return;
            }
            if (isPel) {
                while (ancNode) {
                    if ($B.DomUtils.hasClass(ancNode, "p_element")) {
                        break;
                    }
                    ancNode = ancNode.parentNode;
                }
            }
            return ancNode;
        }
    }
    /**
     * 获取dom region
     * forFocusEl是否获取鼠标所在元素
     * **/
    _getDomRange(forFocusEl) {
        var selection = this._getSelection();
        var region = selection.getRangeAt(0);
        if (forFocusEl) {
            let container = region.commonAncestorContainer;
            if (!region.collapsed) {
                container = region.startContainer;
            }
            if (container.nodeType === 1) {
                return container;
            }
            return container.parentNode;
        }
        return region;
    }
    /**
     * 获取选区信息
     * needEl是否需要保存对应的dom元素，否则只保存id
     * **/
    getRegion(needEl) {
        var region = this._getDomRange();
        var scontainer = region.startContainer;
        var econtainer = region.endContainer;
        //修正当前focus不是在可编辑区域的场景
        if (scontainer.nodeType === 1 && econtainer.nodeType === 1 && $B.Dom.hasClass(scontainer, "_e_btn_")) {
            let $firstEl = this.$input.firstChild;
            this.move2start($firstEl);
            region = this._getDomRange();
            scontainer = region.startContainer;
            econtainer = region.endContainer;
        }
        var startOfs = region.startOffset;
        var endOfs = region.endOffset;
        if (scontainer.nodeType === 1) {
            scontainer = scontainer.firstChild;
            startOfs = 0;
        }
        if (econtainer.nodeType === 1) {
            econtainer = econtainer.firstChild;
            endOfs = econtainer.innerText.length;
        }
        var $s, $e, $sp, $ep, $p, dirStrtId, dirEndId, isCollapsed = region.collapsed;
        if (isCollapsed) { //无选区
            $s = scontainer.parentNode;
            $e = $s;
            $p = this._getPelByChild($e);
            dirStrtId = $p.id;
            dirEndId = dirStrtId;
            $p = this._getRootPel($p);
            $sp = $p;
            $ep = $p;
        } else {//有选区
            $s = scontainer.parentNode;
            $sp = this._getPelByChild($s);
            dirStrtId = $sp.id;
            $e = econtainer.parentNode;
            $ep = this._getPelByChild($e);
            dirEndId = $ep.id;
            $sp = this._getRootPel($sp);
            $ep = this._getRootPel($ep);
        }
        //确保是跟段落
        var rgObj = {
            isCollapsed: isCollapsed,
            startPel: $sp.id,
            endPel: $ep.id,
            startSpan: $s.id,
            endSpan: $e.id,
            startIdx: startOfs,
            endIdx: endOfs,
            dirStrtId: dirStrtId,
            dirEndId: dirEndId
        };
        //console.log($s,$e,$sp,$ep);
        if (needEl) {
            rgObj["$startPel"] = $sp;
            rgObj["$endPel"] = $ep;
            rgObj["$startSpan"] = $s;
            rgObj["$endSpan"] = $e;
        }
        return rgObj;
    }
    _getSelection() {
        var selection;
        if (window.getSelection) {
            selection = window.getSelection();
        } else if (document.selection) {
            selection = document.selection.createRange();
        }
        return selection;
    }
    /**
     * 获取元素$el所在的段落元素
     * @param {*} $s 
     * @returns 
     */
    _getPelByChild($s) {
        var $p = $s;
        while ($p) {
            if ($B.DomUtils.hasClass($p, "p_element")) {
                break;
            }
            $p = $p.parentNode;
        }
        return $p;
    }
    /**
     * 保存选区信息到region变量
     * @param {*} needEl 
     */
    saveRegion(needEl) {
        this.region = this.getRegion(needEl);
    }
    /***
     * 根据暂存的选区信息恢复选区
     */
    rebuildRegion(r) {
        if (r) {
            this.region = r;
        }
        let regn = this.region;
        if (regn) {
            let startPel = regn.startPel;
            let endPel = regn.endPel;
            let startSpan = regn.startSpan;
            let endSpan = regn.endSpan;
            let startIdx = regn.startIdx;
            let endIdx = regn.endIdx;
            let $startP = $B.DomUtils.findbyId(this.$pageWap, startPel);
            if ($startP) {
                let $endP;
                if (startPel === endPel) {
                    $endP = $startP;
                } else {
                    $endP = $B.DomUtils.findbyId(this.$pageWap, endPel);
                }
                let firstEl = $B.DomUtils.findbyId($startP, startSpan);
                let endEl = $B.DomUtils.findbyId($endP, endSpan);
                this.setRegion(firstEl, endEl, startIdx, endIdx);
            }
        }
    }
    /**
     * 移动到 el元素尾部 
     */
    move2end(el) {
        if (!$B.DomUtils.hasClass(el, "p_span")) {
            el = el.lastChild;
            while (el) {
                if ($B.DomUtils.hasClass(el, "p_span")) {
                    break;
                }
                el = el.lastChild;
            }
        }
        el.focus();
        this.setRegionByEl(el, undefined, 1);
    }
    /**
     * 移动到 el元素头部
     */
    move2start(el) {
        if (!$B.DomUtils.hasClass(el, "p_span")) {
            el = el.firstChild;
            while (el) {
                if ($B.DomUtils.hasClass(el, "p_span")) {
                    break;
                }
                el = el.firstChild;
            }
        }
        this.setRegionByEl(el, undefined, 2);
    }
    /**
     * 根据dom元素设置选区
     * @param {*} startEl 元素
     * @param {*} endEl   元素
     * @param {*} flag 1移动到光标结束位置，2移动光标到开始位置
     */
    setRegionByEl(startEl, endEl, flag) {
        if (typeof endEl === "undefined") {
            endEl = startEl;
        }
        var firstChild = startEl.firstChild,
            lastChild = endEl.firstChild,
            startOffset = 0,
            endOffset = lastChild.length;
        if (flag) {
            if (flag === 1) {
                startOffset = endOffset;
            } else {
                if (firstChild.nodeValue[0] === "\u200b") {
                    startOffset = 1;
                }
                endOffset = startOffset;
            }
        }
        this.setRegion(firstChild, lastChild, startOffset, endOffset);
        this.saveRegion();
    }
    /**
     * 设置选区，元素是文本类型，指定开始，结束下标
     * **/
    setRegion(firstChild, lastChild, startOffset, endOffset) {
        if (firstChild.nodeType === 1) {
            firstChild = firstChild.firstChild;
        }
        if (lastChild.nodeType === 1) {
            lastChild = lastChild.firstChild;
        }
        var range = document.createRange();
        range.setStart(firstChild, startOffset);
        range.setEnd(lastChild, endOffset);
        var sel = window.getSelection();
        try {
            sel.removeAllRanges();
        } catch (ex) { }
        sel.addRange(range);
    }
    clearDomSelected() {
        $B.clearDomSelected();
        this.clearCssEls();
        this.region = undefined;
    }
    isSelected() {
        let r = this._getDomRange();
        return !r.collapsed;
    }
    /**
     * 是否存在选区
     * ***/
    hasRegion() {
        let r = this._getDomRange();
        return !r.collapsed;
    }
    /**
     * 是否已经聚焦fous
     * **/
    hasFocus() {
        let r = this._getDomRange();
        let container = r.commonAncestorContainer;
        if (container.nodeType === 3) {
            if ($B.Dom.hasClass(container.parentNode, "p_span")) {
                return true;
            }
        } else {
            if ($B.Dom.hasClass(container, "_input_field") || $B.Dom.hasClass(container, "p_element")) {
                return true;
            }
        }
    }
    destroy() {
        this.URDOINS.destroy();
        this.tableIns.destroy();
        this.ResizeIns.destroy();
        this.URDOINS = undefined;
        this.toolIns = undefined;
        this.tableIns = undefined;
        this.ResizeIns = undefined;
        super.destroy();
    }
}
Keditor.extend = function (obj) {
    Object.assign(this.prototype, obj);
};
$B["Keditor"] = Keditor;
Keditor.extend({
    beforeExecute: function (fn, params, eventEl) {
        let go = this.tableIns.exeCss(fn, params, eventEl);       
        if (go) {
            let neefFocus = !eventEl || $B.Dom.attr(eventEl,"focus");
            if(neefFocus){
                if(!this.hasFocus()){
                    $B.alert({
                        timeout:1.5,
                        position:'top',
                        mask:false,
                        content:editCfg.label.pleaseFocus
                    });
                    return false;
                }               
            }
            if (this.toolIns && this.toolIns.needRegion(fn)) {
                if (this.cssEls.length === 0) {
                    this.getCssEls();
                }
            }
            if (this.cssPEls.length === 0) {
                this.getCssEls(true);
            }
            return true;
        }
        return false;
    },
    afterExecute: function (fn, params, eventEl) {
    },
    /**
     * 高亮选择的段落
     * ***/
    activedLinePELS: function () {
        if (this.cssPEls.length === 0) {
            this.getCssEls(true);
        }
        this.loopPelCssEls(($p) => {
            $B.DomUtils.addClass($p, "k_editor_actived_section");
        });
    },
    /**
     * 取消高亮选择的段落
     * ***/
    unactivedLinePELS: function () {
        this.loopPelCssEls(($p) => {
            $B.DomUtils.removeClass($p, "k_editor_actived_section");
        });
    },
    _getRootPel: function ($p1, retObj) {
        var $pp = $p1;
        while ($pp) {
            if ($B.DomUtils.hasClass($pp.parentNode, "k_edit_input")) {
                break;
            }
            $pp = $pp.parentNode;
            if (retObj) {
                if ($pp.nodeName === "TD") {
                    if (!retObj["isInTd"]) {
                        retObj["isInTd"] = true;
                        retObj["td"] = $pp;
                    }
                } else if ($pp.nodeName === "TABLE") {
                    if (!retObj["table"]) {
                        retObj["table"] = $pp;
                    }
                }
            }
        }
        return $pp;
    },
    _getPelbychild: function ($s) {
        let $p = $s;
        while ($p) {
            if ($B.DomUtils.hasClass($p, "p_element")) {
                break;
            }
            $p = $p.parentNode;
        }
        return $p;
    },
    /**
     * 循环span修饰元素
     * **/
    loopSpanCssEls: function (fn) {
        for (let i = 0, len = this.cssEls.length; i < len; i++) {
            let el = this.cssEls[i];
            fn(el);
            let childs = el.children;
            for (let j = 0; j < childs.length; j++) {
                fn(childs[j]);
            }
        }
    },
    /**
     * 循环段落修饰元素
     * **/
    loopPelCssEls: function (fn) {
        for (let i = 0, len = this.cssPEls.length; i < len; i++) {
            fn(this.cssPEls[i]);
        }
    },
    /**
     * 根据划选的区域分析形成待修饰的tag集合
     * @param not2span 不需要提取span
     * **/
    getCssEls: function (not2span) {
        //console.log("getCssEls");
        if (!this.region) {
            return;
        }
        this.clearCssEls();
        var r = this.region,
            $s1, $s2,
            $p1, $p2;

        $p1 = $B.DomUtils.findbyId(this.$pageWap, r.startPel);
        $p2 = $p1;
        if (r.startPel !== r.endPel) {
            $p2 = $B.DomUtils.findbyId(this.$pageWap, r.endPel);
        }
        if (r.isCollapsed) { //无选区
            $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
            this.cssEls.push($s1);
            this.cssPEls.push($p1);
        } else {
            $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
            if (r.startSpan === r.endSpan) {
                //根据划选下标形成span元素组合 ,并将组合后的span放到 this.cssEls  
                if (!not2span) {
                    let rets = this.splitWrapText($s1, r.startIdx, r.endIdx);
                    let regionEl = this._insertCssSpanEls($s1, rets);
                    this.setRegionByEl(regionEl);
                }
                this.cssPEls.push($p1);
            } else {//跨标签场景，涵盖跨段落场景 
                $s2 = $B.DomUtils.findbyId($p2, r.endSpan);
                let startRegEl = $s1;
                let endRegEl = $s2;
                if (!not2span) {
                    let rets = this.splitWrapText($s1, r.startIdx, $s1.innerText.length);
                    startRegEl = this._insertCssSpanEls($s1, rets);
                    let rets2 = this.splitWrapText($s2, 0, r.endIdx);
                    endRegEl = this._insertCssSpanEls($s2, rets2);
                    this.setRegionByEl(startRegEl, endRegEl);
                    //加入开始选区同级元素
                    let $el = rets;
                    if (Array.isArray(rets)) {
                        $el = rets[rets.length - 1];
                    }
                    let isInSampleP = false;
                    let nextEl = $el.nextSibling;
                    while (nextEl) {
                        if (nextEl === endRegEl) {
                            isInSampleP = true;
                            break;
                        }
                        this.cssEls.push(nextEl);
                        nextEl = nextEl.nextSibling;
                    }
                    //加入结束区域同级元素，需要判断是否是同一个段落的
                    //不在同一个段落才需要做加入
                    if (!isInSampleP) {
                        $el = rets2;
                        if (Array.isArray(rets2)) {
                            $el = rets2[0];
                        }
                        let prevEl = $el.previousSibling;
                        while (prevEl) {
                            this.cssEls.push(prevEl);
                            prevEl = prevEl.previousSibling;
                        }
                    }
                }
                //通过开始，结束选区的标签来处理父级跨选区的span提取加入
                //首先通过提取开始，结束标签所在的段落标签，及其段落标签是容器是否在td单元格范围内，如果是考虑跨表格情况
                let startInfo = {}, endInfo = {};
                let $startPel = this._getRootPel(startRegEl, startInfo);//开始段落
                let $endPel = this._getRootPel(endRegEl, endInfo);//结束段落

                if (!startInfo.isInTd && !endInfo.isInTd) { //选区开始位置，结束位置均不在表格范围内                    
                    this.setbetweenRegion($startPel, $endPel, not2span);
                } else if (startInfo.isInTd && !endInfo.isInTd) { //开始位置在表格内，结束位置不在表格内
                    this.setParentStartRegion(startRegEl, $startPel, $endPel, not2span);
                } else if (!startInfo.isInTd && endInfo.isInTd) { //开始位置不在表格内，结束位置在表格内
                    this.setParentEndRegion(endRegEl, $startPel, $endPel, not2span);
                } else {//开始位置，结束位置均在表格内，
                    if (startInfo.td === endInfo.td) {//同一个单元格内
                        let $startP = this._getPelbychild(startRegEl);
                        let $endP = this._getPelbychild(endRegEl);
                        this.setbetweenRegion($startP, $endP, not2span);
                    }
                }
            }
        }
    },
    setParentEndRegion: function (endRegEl, $startPel, $endPel, not2span) {
        this.setbetweenRegion($startPel, $endPel, not2span);
        this.loopParentRegionEl(endRegEl, $endPel, 'previousSibling', not2span);
    },
    /**
     *嵌套元素场景下，父元素选区提取
     * ***/
    setParentStartRegion: function (startEl, $startPel, $endPel, not2span) {
        //提取开始段落的选区
        this.loopParentRegionEl(startEl, $startPel, 'nextSibling', not2span);
        this.setbetweenRegion($startPel, $endPel, not2span);
    },
    setbetweenRegion: function ($startPel, $endPel, not2span) {
        if ($B.DomUtils.hasClass($startPel, "p_element")) {
            this.cssPEls.push($startPel);
        }
        if ($startPel !== $endPel) {
            let nextEl = $startPel.nextSibling;
            while (nextEl) {
                if (nextEl === $endPel) {
                    break;
                }
                if ($B.DomUtils.hasClass(nextEl, "p_element")) {
                    this.cssPEls.push(nextEl);
                }
                this.putPelChilds2CssEls(nextEl, not2span);
                nextEl = nextEl.nextSibling;
            }
            if ($B.DomUtils.hasClass($endPel, "p_element")) {
                this.cssPEls.push($endPel);
            }
        }
    },
    loopParentRegionEl: function (startEl, $rootPel, siblingKey, not2span) {
        let $p = startEl.parentNode;
        if ($p === $rootPel) {
            return;
        }
        let nextEl = $p[siblingKey];
        while (nextEl) {
            if ($B.DomUtils.hasClass(nextEl, "p_element")) {
                this.cssPEls.push(nextEl);
            }
            this.putPelChilds2CssEls(nextEl, not2span);
            nextEl = nextEl[siblingKey];
        }
        this.loopParentRegionEl($p, $rootPel, siblingKey, not2span);
    },
    putPelChilds2CssEls: function ($p, not2span) {
        if ($p.firstChild.nodeName === "TABLE") { //是表格
            let table = $p.firstChild;
            let body = table.firstChild;
            let trs = body.children;
            for (let i = 0; i < trs.length; i++) {
                let tds = trs[i].children;
                for (let j = 0; j < tds.length; j++) {
                    let plist = tds[j].children;
                    for (let m = 0; m < plist.length; m++) {
                        this.putPelChilds2CssEls(plist[m]);
                    }
                }
            }
        } else {
            let childs = $p.children;
            if ($B.DomUtils.hasClass($p, "p_element")) {
                let put = true;
                for(let i = 0 ;i < this.cssPEls.length ;i++){
                    if(this.cssPEls[i] === $p){
                        put = false;
                        break;
                    }
                }
                if(put){
                    this.cssPEls.push($p);
                }                
            }
            for (let i = 0; i < childs.length; i++) {
                let $i = childs[i];
                if (!not2span && $i.nodeName === "SPAN" && $B.DomUtils.hasClass($i, "p_span")) {
                    this.cssEls.push($i);
                } else {
                    this.putPelChilds2CssEls($i);
                }
            }
        }
    },
    /**
     * 将开始regin，结束region拆分好的span插入替换到相应的位置
     * ***/
    _insertCssSpanEls: function ($s1, rets) {
        let regionEl;
        if (Array.isArray(rets)) {
            let $firstEl;
            for (let i = 0; i < rets.length; i++) {
                if (i === 0) {
                    $firstEl = rets[i];
                    $B.DomUtils.replace($s1, rets[i]);
                } else {
                    $B.DomUtils.after($firstEl, rets[i]);
                    $firstEl = rets[i];
                }
                if ($B.DomUtils.hasClass(rets[i], "_region_span")) {
                    $B.DomUtils.removeClass(rets[i], "_region_span");
                    regionEl = rets[i];
                    this.cssEls.push(regionEl);
                }
            }
        } else {
            regionEl = rets;
            if ($B.DomUtils.hasClass(regionEl, "_region_span")) {
                $B.DomUtils.removeClass(regionEl, "_region_span");
            }
            this.cssEls.push(rets);
        }
        return regionEl;
    },
    //对标签根据选区进行拆分
    splitWrapText: function ($el, start, end) {
        let text = $el.innerText;
        let len = text.length;
        //先处理不可见字符，纠正start，end下标
        if (text[0] === "\u200B") {
            text = text.replace("\u200B", "");
            if (start > 0) {
                start = start - 1;
            }
            end = end - 1;
        }
        if (text[len - 1] === "\u200B") {
            text[len - 1] = "";            
            if (end === len) {
                end = end - 1;
            }
        }
        len = text.length;
        if (len === end && start === 0) {
            $B.DomUtils.addClass($el, "_region_span");
            setTimeout(()=>{
                $B.DomUtils.removeClass($el, "_region_span");
            },666);
            return $el;
        }
        let cssObj = $B.style2cssObj($el);
        let ret = [], txt, $span;
        if (start > 0) {
            txt = text.slice(0, start);
            $span = this.createSpanEl();
            $B.DomUtils.css($span, cssObj);
            $span.innerText = "\u200B" + txt;
            ret.push($span);
        }
        //这个是选区span
        $span = this.createSpanEl();
        $B.DomUtils.addClass($span, "_region_span");
        txt = text.slice(start, end);
        $span.innerText = "\u200B" + txt;
        $B.DomUtils.css($span, cssObj);
        ret.push($span);
        if (len > end) {
            txt = text.slice(end, len);
            $span = this.createSpanEl();
            $span.innerText = "\u200B" + txt;
            ret.push($span);
            $B.DomUtils.css($span, cssObj);
        }
        setTimeout(()=>{
            for(let i = 0; i < ret.length ;i++){
                $B.DomUtils.removeClass(ret[i], "_region_span");
            }        
        },666);
        return ret;
    },
    /**
     * 根据选区/光标抽取css集合，用于工具栏联动
     * ***/
    extractCss: function () {
        let ret = this.getSpanAndPCss();
        var cssSpanMap = ret.spanCss;
        var cssPelMap = ret.pCss;
        let cssMap = $B.extendObjectFn(cssSpanMap, cssPelMap);
        return cssMap;
    },
    getSpanAndPCss:function(){
        var cssSpanMap = UTILS.getSpanDefcss();
        var cssPelMap = UTILS.getPelDefCss();        
        var r = this.region, $p1, $p2, isCrossPel = r.startPel !== r.endPel, $s1, $s2;
        $p1 = $B.DomUtils.findbyId(this.$pageWap, r.dirStrtId);
        $p2 = $p1;
        if (isCrossPel) {
            $p2 = $B.DomUtils.findbyId(this.$pageWap, r.dirEndId);
        }
        if (r.isCollapsed) { //无选区
            UTILS.extractPcss($p1, cssPelMap);//先提取行样式
            $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
            UTILS.extractSpancss($s1, cssSpanMap);
        } else {//存在选区
            if (isCrossPel) { //跨段落
                UTILS.extractPcss($p1, cssPelMap);//先提取行样式
                $s1 = $B.DomUtils.findbyId($p1, r.startSpan);//提取开始行里面的span选区
                UTILS.extractSpancss($s1, cssSpanMap);
                let nextPel = $p1.nextSibling;
                while (nextPel) {
                    if (nextPel === $p2) { //结束段落
                        UTILS.extractPcss(nextPel, cssPelMap);//先提取行样式
                        $s2 = $B.DomUtils.findbyId(nextPel, r.endSpan);
                        let $1 = nextPel.firstChild;
                        while ($1) {
                            UTILS.extractSpancss($1, cssSpanMap);
                            if ($1 === $s2) {
                                break;
                            }
                            $1 = $1.nextSibling;
                        }
                    } else {//中间段落
                        UTILS.extractPcss(nextPel, cssPelMap);//先提取行样式
                        let childs = nextPel.children;
                        for (let i = 0; i < childs.length; i++) {
                            UTILS.extractSpancss(childs[i], cssSpanMap);
                        }
                    }
                    nextPel = nextPel.nextSibling;
                }
            } else {//同一个段落
                UTILS.extractPcss($p1, cssPelMap);//先提取行样式
                $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
                if (r.startSpan !== r.endSpan) { //跨标签
                    $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
                    $s2 = $B.DomUtils.findbyId($p1, r.endSpan);
                    while ($s1) {
                        UTILS.extractSpancss($s1, cssSpanMap);
                        if ($s1 === $s2) {
                            break;
                        }
                        $s1 = $s1.nextSibling;
                    }
                } else {//同一个标签内                   
                    $s1 = $B.DomUtils.findbyId($p1, r.startSpan);
                    UTILS.extractSpancss($s1, cssSpanMap);
                }
            }
        }
        return {spanCss:cssSpanMap,pCss:cssPelMap};
    },
    /**
     * 获取一个段落元素
     * ***/
    createPEl: function () {
        return UTILS.createPEl();
    },
    createSpanEl: function () {
        return UTILS.createSpanEl();
    },
    loopUpdateId: function (el) {
        var id = $B.generateDateUUID();
        el.id = id;
        var childs = el.children;
        for (let i = 0; i < childs.length; i++) {
            if (childs[i].tagName !== "BR") {
                this.loopUpdateId(childs[i]);
            }
        }
    },
    /**
     * 在$p段落后插入一行，返回该行对象
     * @param $p 
     * @param flag  不需要span元素 
     */
    insertNewPAfter: function ($p, flag) {
        let newel = UTILS.createPEl(flag);
        $B.DomUtils.after($p, newel);
        return newel;
    },
    /***
     * 移除span嵌套
     * **/
    removeNestSpan: function ($el) {
        if ($el.tagName === "SPAN") {

        } else {
            var childs = $el.children;
            for (let i = 0; i < childs.length; i++) {
                this.removeNestSpan(childs[i]);
            }
        }
    },
    changeSelectionColor: function (cssName, cssValue) {
        if (!this.$docHeader) {
            this.$docHeader = document.getElementsByTagName('head')[0];
        }
        var extCss = "";
        if (cssName === "color") {
            extCss = ";background-color:#3390FF;";
        }
        var style = '.k_edit_input *::selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + extCss + '}' +
            '.k_edit_input *::-moz-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + extCss + '}' +
            '.k_edit_input *::-webkit-selection ,.k_editor_float_input  *::selection{' + cssName + ':' + cssValue + extCss + '}';
        var $t = $B.DomUtils.findbyId(this.$docHeader, "#_selection_style");
        if ($t) {
            this.$docHeader.removeChild($t);
        }
        var snode = document.createElement("style");
        snode.id = "_selection_style";
        snode.type = "text/css";
        if (snode.styleSheet) {
            snode.styleSheet.cssText = style;
        } else {
            snode.innerHTML = style;
        }
        this.$docHeader.appendChild(snode);
    },
    clearSelectionColor: function () {
        if (this.$docHeader) {
            var $t = $B.DomUtils.findbyId(this.$docHeader, "#_selection_style");
            if ($t) {
                this.$docHeader.removeChild($t);
            }
        }
    },
    /**
     * 循环元素里面span标签
     * **/
    loopPelSapn: function ($el, fn) {
        let childs = $el.children;
        for (let i = 0; i < childs.length; i++) {
            let child = childs[i];
            if (child.tagName === "SPAN") {
                fn(child);
            } else {
                this.loopPelSapn(child, fn);
            }
        }
    },
    hideCtxMenu: function () {
        if (this.$ctxMenu) {
            this.$ctxMenu.style.display = "none";
        }
    },
    showCtxMenu: function (pos) {
        if (!this.$ctxMenu) {
            let opts = {
                title: "",
                onClosed: ($l) => {
                    this.hideCtxMenu();
                },
                onCreated: ($b) => {
                    let ctxMenus = editCfg.ctxMenus;
                    UTILS.createCtxItem(ctxMenus,$b,(el,e)=>{
                        this.hideCtxMenu();
                        let fn = $B.Dom.attr(el, "fn");
                        if (this[fn]) {
                            this[fn](e);
                        }else{
                            console.log(fn + " is not found");
                        }
                    });                  
                    this.bindFocusEv($b);
                }
            };
            this.$ctxMenu = UTILS.createCommPanel(opts);
        }
        UTILS.showPanel(this.$ctxMenu,pos);
    },
    openInsertTable: function () {
        this.tableIns.openInsertTable((prs) => {
            this.insertTableFn(prs);
        });
    },
    openInsertFile: function (e) {
        this.toolIns.uploadFnMaker("uploadFn",{top:e.pageY - 20,left:e.pageX-10} );
    },
    openInsertImage: function (e) {
        this.invokeToolMaker("pictureFn", e);
    },
    openInsertLink: function (e) {
        this.invokeToolMaker("linkFn", e);
    },
    onOpenLinkPanel: function ($b) {
        let r = this.getRegion();
        if (!r.isCollapsed) {
            if (r.dirStrtId !== r.dirEndId) {
                $B.alert({
                    content: editCfg.label.unsuport,
                    timeout: 2,
                    onClosed: () => {
                        this.toolIns.hidePanel();
                    }
                });
                return false;
            }
            let $name = $B.Dom.findbyId($b, "_link_name");
            let $addr = $B.Dom.findbyId($b, "_addr_url");
            this.getCssEls();
            let firstEl = this.cssEls[0];
            let txt = [];
            txt.push(firstEl.innerText);
            let rms = [];
            if (this.cssEls.length > 1) {
                let i = 1;
                while (i < this.cssEls.length) {
                    txt.push(this.cssEls[i].innerText);
                    i++;
                    rms.push(this.cssEls[i]);
                }
            }
            $name.value = txt.join("");
        }
    },
    openInsertEmotion: function () {

    },
    openGraph: function (e) {
       this.toolIns.paragraphFnMaker("paragraphFn",{top:e.pageY - 60,left:e.pageX-10} );
    },
    invokeToolMaker: function (fn, e) {
        let pos = {
            top: e.pageY,
            left: e.pageX
        };
        let method = fn + "Maker";
        this.toolIns[method](fn, pos);
    },
    showLinkMenu: function (el) {
        if (!this.$linkMenu) {
            let opts = {
                title: "",
                onClosed: ($l) => {
                    this.hidenLinkMenu();
                },
                onCreated: ($b) => {
                    let $f = $B.Dom.createEl(editCfg.linkMenu);
                    $B.Dom.append($b, $f);
                    this.bindFocusEv($b);
                    $B.Dom.click($B.Dom.findbyId($f, "_del_link"), (e) => {
                        if (this.curLinkTag) {
                            let el = this.curLinkTag.parentNode;
                            el.innerText = "\u200b";
                            $B.Dom.removeAttr(el,"contenteditable");
                            this.setRegionByEl(el, el, 1);
                        }
                        this.hidenLinkMenu();
                    });
                }
            };
            this.$linkMenu = UTILS.createCommPanel(opts);
        }
        if (el.nodeName === "SPAN") {
            el = el.firstChild;
        }
        let href = $B.Dom.attr(el, "href");
        let txt = el.innerText;
        let $a = $B.Dom.findbyId(this.$linkMenu, "_op_link");
        $a.href = href;
        $a.innerText = txt;
        let pos = $B.Dom.offset(el);
        pos.top = pos.top + 22;
        pos.left = pos.left + $B.Dom.width(el) - 8;      
        UTILS.showPanel(this.$linkMenu,pos);
        this.curLinkTag = el;
    },
    hidenLinkMenu: function () {
        this.curLinkTag = undefined;
        if (this.$linkMenu) {
            this.$linkMenu.style.display = "none";
        }
    },
    showImgMenu:function(el,e){        
        if(el.nodeName === "SPAN"){
            el = el.firstChild;
        }
        if(e.which === 3){
            if (!this.$imgMenu) {
                let opts = {
                    title: "",
                    onClosed: ($l) => {
                        this.hidenImgMenu();
                    },
                    onCreated: ($b) => {
                        let ctxMenus = editCfg.imgMenus;
                        UTILS.createCtxItem(ctxMenus,$b,(el,e)=>{
                            this.hidenImgMenu(); 
                            let fn = $B.Dom.attr(el, "fn");
                            if (this[fn]) {
                                this[fn](e);
                            }else{
                                console.log(fn + " is not found");
                            }
                        });                      
                        this.bindFocusEv($b);                       
                    }
                };
                this.$imgMenu = UTILS.createCommPanel(opts);
            }
            let pos = $B.Dom.offset(el);
            let w = $B.Dom.outerWidth(el);
            let h = $B.Dom.outerHeight(el);
            pos.top = pos.top + h;
            pos.left = pos.left + w;
            UTILS.showPanel(this.$imgMenu,pos);
            this.curImgTag = el;
            clearTimeout(this.clearCurImgTimer);
        }else{//拖拉调整
            this.ResizeIns.bind(el);
        }
    },
    editImgFn:function(e){
        clearTimeout(this.clearCurImgTimer);             
        let $fb = this.toolIns.editImgMaker("pictureEditFn",{top:e.pageY - 30,left:e.pageX -40});
        let w = $B.Dom.width(this.curImgTag);
        let h = $B.Dom.height(this.curImgTag);
        let paddingTop = $B.Dom.css(this.curImgTag,"padding-top");
        let paddingRight = $B.Dom.css(this.curImgTag,"padding-right");
        let paddingBottom = $B.Dom.css(this.curImgTag,"padding-bottom");
        let paddingLeft = $B.Dom.css(this.curImgTag,"padding-left");
        let $top = $B.Dom.findbyId($fb,"_top_k_padding");
        let $bottom = $B.Dom.findbyId($fb,"_bottom_k_padding"); 
        let $left = $B.Dom.findbyId($fb,"_left_k_padding");
        let $right = $B.Dom.findbyId($fb,"_right_k_padding");
        let $width = $B.Dom.findbyId($fb,"_img_width");
        let $height = $B.Dom.findbyId($fb,"_img_height");
      
        $top.value = paddingTop;
        $right.value = paddingRight;
        $bottom.value = paddingBottom;
        $left.value = paddingLeft;
        w = w - paddingLeft - paddingRight;
        h = h - paddingTop - paddingBottom;
        $width.value = w;
        $height.value = h ;
    },
    borderImgFn:function(e){        
        clearTimeout(this.clearCurImgTimer);
        let $fb = this.toolIns.borderImgMaker("pictureBorderFn",{top:e.pageY - 50,left:e.pageX -50});
    },
    hidenImgMenu:function(el){  
        clearTimeout(this.clearCurImgTimer);
        this.clearCurImgTimer = setTimeout(()=>{
            this.curImgTag = undefined;            
        },500);             
        if (this.$imgMenu) {
            this.$imgMenu.style.display = "none";
        }
    },
    deleteImgFn:function(){
        if( this.curImgTag){
            let prt = this.curImgTag.parentNode;
            this.curImgTag = undefined;           
            prt.innerHTML = "\u200b";
            $B.Dom.removeAttr(prt,"contenteditable");
            this.move2end(prt);
        }
    }, 
    clearHtmlStr: function (contents) {
        if (contents !== "") {
            contents = contents.replace(/[\n\r]/g, '').replace(/\s+</g, "<").replace(/>\s+/g, ">").replace(/(^\s*)|(\s*$)/g, "");
        }
        return contents;
    },
    createImage: function (prs) {
        if (typeof prs.width === "undefined") {
            prs.width = "auto";
        }
        if (typeof prs.height === "undefined") {
            prs.height = "auto";
        }
        let $img = $B.Dom.createEl("<img id='" + $B.getUUID() + "' tabindex='0' src='" + prs.url + "' style='width:" + prs.width + "px;height:" + prs.height + "px' />");
        return $img;
    },
    createLinkA:function(params){
        let $img = $B.Dom.createEl("<a id='" + $B.getUUID() + "' tabindex='0' href='" + params.url + "' target='_blank' >"+params.name+"</a>");
        return $img;
    },
    callOffBrush:function(){       
        if(this.$brushBtn){
            $B.Dom.removeClass(this.$brushBtn.firstChild,"k_edit_brush_actived")
        }        
        this.BrushingCSS = undefined;
        if(this.$movingBrushMouseEl){
            this.$movingBrushMouseEl.style.display = "none";
        }
    },
    bindTableEvents($tab){
        
        this.tableIns.bindEvents($tab);
    },
    /**
     * 检查分析段落是否为list（数值，图标样式）
     * return ""
     * **/
    anyliscList($p){
        while($p){
            if($p.nodeName === "DIV"){
                break;
            }
            $p = $p.parentNode;
        }
        let $s = $p.firstChild;         
        if($s.nodeName === "SPAN"){            
            let txt = $s.innerText;
            txt = txt.replaceAll("\u200b","");
            let mats = this.matchSEQReg(txt);
            if(mats){                
                let idxText = mats[0];
                let num = mats[2];
                let numNext = parseInt(num) + 1;
                let nextIdx = idxText.replace(num,numNext);
                let ret = {
                    num: true,
                    nextIdx: nextIdx
                };
                if(!/^(\s*)(\d+)\s*[、.]\s*$/.test(txt)){
                    ret["prePel"] = $p;
                    ret["idxText"] = idxText;
                }
                return ret;
            }
        }
    },
    matchSEQReg(txt){
        txt = txt.replace(/\u200b/,"");
        let mats = txt.match(/^(\s*)(\d+)\s*[、.\)）]\s*/);
        return mats;
    },
    /**
     * 回车更新序列
     * **/
    updateListSeq($p,prs){
        if(prs.num || prs.zhNum){
            let $nextP = $p;
            while($nextP){
                let $s = $nextP.firstChild;
                if($s.nodeName !== "SPAN"){
                    break;
                }
                let txt = $s.innerText.replace(/\u200b/,"");
                let mats = this.matchSEQReg(txt);
                if(mats){
                    console.log(mats);
                    let idxText = mats[0]; 
                    let num = mats[2];                                                            
                    if(prs.num){
                        //替换数字后检测一下格式是否一致（空格、点号）
                        let stype1 = prs.nextIdx.replace(/\d+/g,"");
                        let stype2 = idxText.replace(/\d+/g,"");
                        if(stype1 !== stype2){//格式不一致
                            break;
                        }
                        let numNext ;
                        if(prs.usePrs){
                            if(prs._curIdx){
                                numNext = prs._curIdx + 1;
                            }else{
                                numNext = parseInt( prs.nextIdx.match(/\d+/));                                
                            }
                            prs._curIdx = numNext;
                        } else{
                            numNext = parseInt(num) + 1;
                        }                       
                        $s.innerText = "\u200b" + idxText.replace(num,numNext);
                    }                   
                }else{
                    break;
                }
                $nextP = $nextP.nextSibling;
            }
        }        
    },
    /**
     * color：颜色
     * fontSize：字体图标大小
     * iconCls：字体样式名称
     * **/
    getFontIconBase64(color,fontSize,iconCode){
        if(!this.$iconCavas){
            let $wap = $B.Dom.createEl('<div style="position:absolute;top:0px;left:0px;"><canvas></canvas><span></span></div>');
            this.$iconCavas = $wap.firstChild;
            this.$iconText = $wap.lastChild;
            $B.Dom.append(document.body,$wap);
            
        }
        this.$iconText.innerHTML = iconCode;
        var width = fontSize;
        var height = width;

        var context = this.$iconCavas.getContext('2d');
        context.fillStyle = color;
        context.font = fontSize + 'px fontello';
        context.fillText(this.$iconText.innerText, 0, height - 2, width);
        var dataURL = this.$iconCavas.toDataURL("image/png");
        console.log(dataURL);
    },
    /**
     * 创建页
     * ***/
    createDocPage(bindEvents){
        let $p = this.createPEl();       
        if(this.opts.mutilPage){ //如果是多页功能
            let pgCfg = editCfg.pagesCfg.prpValues.page;
            let width = parseInt( pgCfg.pageWidth) + 2  ;
            let height = parseInt( pgCfg.pageHeight) + 2 ;
            let $pageWap = $B.Dom.createEl("<div class='k_box_size k_edit_page_wap' style='overflow:visible;width: "+width+"px;height:"+height+"px;margin:15px auto;position: relative; box-shadow: 0 0 5px rgb(0 0 0 / 10%);border: 1px #d3d3d3 solid;background:#fff;position:relative;'></div>");
            let $pageBack = $B.Dom.append($pageWap,"<div style='position:absolute;top:0;left:0;width:100%;height:100%;' class='pg_back_wap k_box_size'></div>");
            let $pageInput = $B.Dom.append($pageWap,"<div style='position:absolute;top:0;left:0;width:100%;height:100%;' class='pg_input_wap k_box_size'><div  spellcheck='false' contenteditable='true' class='k_edit_input _input_field k_box_size' style='width:100%;height:100%;'></div></div>");            
            $B.DomUtils.append($pageInput.firstChild, $p);
            $B.Dom.append($pageWap, "<div id='page_right_eara' class='k_box_size sibar_eara' style='height:100%;display:none;position:absolute;top:0px;right:0px;'><div class='k_box_size _line' style='width:0px;height:0;border-left:1px dashed #E5E5E5;position:absolute;'></div></div>");
            $B.Dom.append($pageWap, "<div id='page_left_eara'  class='k_box_size sibar_eara' style='height:100%;display:none;position:absolute;top:0px;left:0px;'><div  class='k_box_size _line' style='width:0px;height:0px;border-right:1px dashed #E5E5E5;position:absolute;'></div></div>");
            $B.Dom.append($pageWap, "<div id='page_top_eara'  class='k_box_size sibar_eara'  style='width:100%;display:none;position:absolute;left:0px;top:0px;'><div  class='k_box_size _line'  style='width:0px;height:0px;border-bottom:1px dashed #E5E5E5;position:absolute;'></div></div>");
            $B.Dom.append($pageWap, "<div id='page_bottom_eara'  class='k_box_size sibar_eara'  style='width:100%;display:none;position:absolute;left:0px;bottom:0px;'><div  class='k_box_size _line'  style='width:0px;height:0px;border-top:1px dashed #E5E5E5;position:absolute;'></div></div>");
            if(bindEvents){
                setTimeout(()=>{
                    this.bindPageEvents($pageWap);
                },100);
            }
            return $pageWap;
        }
        let $pageWap = $B.Dom.createEl("<div class='k_box_size k_edit_page_wap' style='background:#fff;width:100%;height:100%;padding:2px 2px;overflow: auto;'><div  spellcheck='false' contenteditable='true' class='k_edit_input _input_field k_box_size' style='width:100%;height:100%;'></div></div>");
        $B.DomUtils.append($pageWap.firstChild, $p);
        return $pageWap;
    },
    /**获取富文本主体元素的视窗偏移量***/
    getElObjOfs(){
        if(this._mainofs){
            return this._mainofs;
        }
        this._mainofs = $B.Dom.offset(this.elObj);
        return this._mainofs;
    }
});
class Table extends $B.BaseControl {
    constructor(editIns) {
        super();
        this.splitNearVal = 4;
        this.selectedTdArray = [];
        this.cssPelist = [];
        this.minRowHeight = 10;
        this.mutilSelect = false;
        this.editIns = editIns;
        var _this = this;
        this.colorIns = editIns.getColorIns("tableColor", function (hex, opacity) {            
            _this.$colorEL.style.backgroundColor = hex;
            clearTimeout(_this.exeColorTimer);
            _this.exeColorTimer = setTimeout(() => {
                _this[_this.colorCaller]({ color: hex, opacity: opacity });
            }, 300);
        });
    }
    exeCss(fn, params, eventEl) {
        if (params && (params.color
            || params["border-top"]
            || params["border-right"]
            || params["border-bottom"]
            || params["border-left"]
            || params["background-color"])) {
            this.holdColorCtl = true;
        }
        this.hidePanel();
        this.holdColorCtl = false;
        if (this.editIns.isSelected()) {
            if (fn !== "ppadding" && fn !== "plineHeight"
                && fn !== "pborderFn" && fn !== "pindentFn"
                && fn !== "pcolorFn" && fn !== "pbackground"
            ) {
                return true;
            }
        }       
        if (this.clickedTd && typeof this[fn] === "function") {
            let table = this.getTableByTd(this.clickedTd);
            this.setTarget(table);
            let ret = false;
            //先生成一个撤销记录
            let prtEl = this.getRootPelByTable(table);
            this.editIns.makeUndoData(prtEl);
            let r = this[fn](params, eventEl);
            if (typeof r !== "undefined") {
                ret = r;
            }            
            if(r){
                this.editIns.clearUndoingData();
            }else{
                //插入一个撤销记录
                this.editIns.putUndoData(1);
            }
            return ret;
        }
        return true;
    }
    activedLinePELS() {
        let plist = [];
        if (this.isSelectedTds()) {
            this.foreachSeletedTds((td) => {
                this.extractTdPel(td, plist);
            });
        } else {
            if (this.editIns.isSelected()) {
                //console.log(this.editIns.cssPEls);
                let els = this.clickedTd.firstChild.firstChild.children;
                let startPelId = this.editIns.region.dirStrtId;
                let endPelId = this.editIns.region.dirEndId;
                for (let i = 0; i < els.length; i++) {
                    if (els[i].id === startPelId) {
                        plist.push(els[i]);
                        break;
                    }
                }
                if (startPelId !== endPelId) {
                    let nextp = plist[0].nextSibling;
                    while (nextp) {
                        plist.push(nextp);
                        if (nextp.id === endPelId) {
                            break;
                        }
                    }
                }
            } else {
                this.extractTdPel(this.clickedTd, plist);
            }
        }
        this.cssPelist = plist;
        for (let i = 0; i < this.cssPelist.length; i++) {
            $B.DomUtils.addClass(this.cssPelist[i], "k_editor_actived_section");
        }
        this.graphOpening = true;
    }
    unactivedLinePELS() {
        this.graphOpening = false;
        for (let i = 0; i < this.cssPelist.length; i++) {
            $B.DomUtils.removeClass(this.cssPelist[i], "k_editor_actived_section");
        }
        this.cssPelist = [];
    }
    resetCss(tabel){
       let trs = tabel.firstChild.children;
       for(let i =0 ; i < trs.length ;i++){
            let tr = trs[i];
            let tds = tr.children;
            for(let j =0 ;j < tds.length ;j++){
                let $wap = tds[j].firstChild.firstChild;
                if($wap.children.length === 1 && $wap.firstChild.firstChild.nodeName === "TABLE"){
                    this.resetCss($wap.firstChild.firstChild);
                }else{
                    let plist = $wap.children;
                    for(let p =0 ; p < plist.length ;p++){
                        let $p = plist[p];
                        $B.Dom.attr($p,{style: editCfg.pElementCss});
                        let $sps = $p.children;
                        for(let k =  0; k < $sps.length ;k++){
                            $B.Dom.attr($sps[k],{style: editCfg.spanCss});
                        }
                    }
                }
            }
       }
    }
    forPels(fn) {
        for (let i = 0; i < this.cssPelist.length; i++) {
            fn(this.cssPelist[i]);
        }
    }
    extractTdPel(td, plist) {
        let childs = td.firstChild.firstChild.children;
        for (let i = 0; i < childs.length; i++) {
            plist.push(childs[i]);
        }
    }
    setTarget(el) {
        this.tableEl = el;
    }
    clearTarget() {
        this.tableEl = undefined;
    }
    clearClickTd() {
        if (this.clickedTd) {
            $B.DomUtils.removeClass(this.clickedTd, 'k_edit_selected_td_shadow');
            this.clickedTd = undefined;
        }
    }
    setClickTd(td) {
        this.clearClickTd();
        $B.DomUtils.addClass(td, "k_edit_selected_td_shadow");
        if(td.nodeName !== "TD"){
            console.log("set k_edit_selected_td_shadow");
        }
        this.clickedTd = td;
    }
    isEmptyTd(td) {
        let $wap = td.firstChild.firstChild;
        let childs = $wap.children;
        for (let i = 0; i < childs.length; i++) {
            let p = childs[i];
            if (p.firstChild && p.firstChild.nodeName === "TABLE") {
                return false;
            }
            if (p.innerText.replaceAll("\u200b", "") !== "") {
                return false;
            }
        }
        return true;
    }
    getTdKey(td) {
        return $B.DomUtils.attribute(td, "row") + "_" + $B.DomUtils.attribute(td, "col");
    }
    getFocusEl(tabEl) {
        let tr = tabEl.firstChild.firstChild;
        let ret = this.getFocusElFromTd(tr.firstChild);
        if (ret) {
            return ret;
        }
        tr = tr.nextSibling;
        while (tr) {
            ret = this.getFocusElFromTr(tr.firstChild);
            if (ret) {
                break;
            }
            tr = tr.nextSibling;
        }
        return ret;
    }
    getFocusElFromTd(td) {
        let el = td.firstChild.firstChild;
        let ret;
        while (el) {
            if ($B.DomUtils.hasClass(el, "p_span")) {
                ret = el;
                break;
            }
            el = el.firstChild;
        }
        if (ret) {
            return ret;
        }
        let nextTd = td.nextSibling;
        while (nextTd) {
            ret = this.getFocusElFromTd(nextTd);
            if (ret) {
                break;
            }
            nextTd = nextTd.nextSibling;
        }
        return ret;
    }
    focusTable(tabEl) {
        let firstSpan = this.getFocusEl(tabEl);
        this.editIns.move2end(firstSpan);
        return firstSpan;
    }
    focusTd(td) {
        if (!td) {
            td = this.clickedTd;
        }
        if (td) {
            this.editIns.move2start(td.firstChild.firstChild.firstChild);
        }
    }
    getTableByTd(td) {
        let $p = td.parentNode;
        while ($p) {
            if ($p.nodeName === "TABLE") {
                break;
            }
            $p = $p.parentNode;
        }
        return $p;
    }
    getRootPelByTd(td){
        let tabEL = this.getTableByTd(td);
        return this.getRootPelByTable(tabEL);
    }
    getRootPelByTable(tabEL){
        let prtEl = tabEL.parentNode;
        while(prtEl){
            if($B.Dom.hasClass(prtEl,"p_element")){
                if($B.Dom.hasClass(prtEl.parentNode,"k_edit_input")){
                    break;
                }
            }
            prtEl = prtEl.parentNode;
        }
        return prtEl;
    }
    getTableByTr(tr) {
        return this.getTableByTd(tr);
    }
    changeCursor(cursor) {
        if (this.tableEl) {
            this.changeTableCursor(this.tableEl, cursor);
        }
    }
    changeTableCursor(tableEl, cursor) {
        this.foreachTd(tableEl, (td) => {
            td.style.cursor = cursor;
            let wrap = td.firstChild.firstChild;
            let childs = wrap.children;
            for (let i = 0; i < childs.length; i++) {
                childs[i].style.cursor = cursor;
            }
        });
    }
    foreachTd(tableEl, fn) {
        var trs = tableEl.firstChild.children;
        for (let i = 0; i < trs.length; i++) {
            let tr = trs[i];
            let tds = tr.children;
            let isLastRow = i === trs.length - 1;
            for (let j = 0; j < tds.length; j++) {
                let args = {
                    rowNum: i,
                    colNum: j,
                    isLastRow: isLastRow,
                    islastCol: j === tds.length - 1
                };
                fn(tds[j], args);
            }
        }
    }
    clearSelected(clearALl) {
        for (let i = 0; i < this.selectedTdArray.length; i++) {
            $B.DomUtils.removeClass(this.selectedTdArray[i], 'k_edit_td_selected');
        }
        this.selectedTdArray = [];
        if (clearALl && this.clickedTd) {
            if (clearALl) {
                this.clearClickTd();
            }
        }
    }
    onRemoved() {
        this.clickedTd = undefined;
        this.selectedTdArray = [];
    }
    isSelectedTds() {
        return this.selectedTdArray.length > 0;
    }
    foreachSeletedTds(fn) {
        for (let i = 0; i < this.selectedTdArray.length; i++) {
            fn(this.selectedTdArray[i]);
        }
        return this.selectedTdArray.length > 0;
    }
    cancelMutilSelect() {
        this.mutilSelect = false;
    }
    makeSelectedUi() {
        if (!this.clickedTd) {
            return;
        }
        var row0 = parseInt($B.DomUtils.attribute(this.clickedTd, "row"));
        var col0 = parseInt($B.DomUtils.attribute(this.clickedTd, "col"));
        var row1 = parseInt($B.DomUtils.attribute(this.movingTd, "row"));
        var col1 = parseInt($B.DomUtils.attribute(this.movingTd, "col"));
        var rowspan = $B.DomUtils.attribute(this.movingTd, "rowspan");
        var colspan = $B.DomUtils.attribute(this.movingTd, "colspan");
        if (rowspan) {
            row1 = row1 + parseInt(rowspan) - 1;
        }
        if (colspan) {
            col1 = col1 + parseInt(colspan) - 1;
        }
        this.clearSelected();
        var startRow, startCol, endRow, endCol;
        if (row1 > row0) {
            startRow = row0;
            endRow = row1;
        } else {
            startRow = row1;
            endRow = row0;
        }
        if (col1 > col0) {
            startCol = col0;
            endCol = col1;
        } else {
            startCol = col1;
            endCol = col0;
        }
        this.foreachAddSelected(startRow, endRow, startCol, endCol);
    }
    foreachAddSelected(startRow, endRow, startCol, endCol) {
        let trs = this.getTableByTd(this.clickedTd).firstChild.children;
        let maxRow = endRow,
            maxCol = endCol,
            tdArr = [];
        for (let i = 0; i < trs.length; i++) {
            if (i < startRow || i > endRow) {
                continue;
            }
            let tds = trs[i].children;
            for (let j = 0; j < tds.length; j++) {
                let td = tds[j];
                let colIdx = parseInt($B.DomUtils.attribute(td, "col"));
                if (colIdx < startCol || colIdx > endCol) {
                    continue;
                }
                tdArr.push(td);
                $B.DomUtils.addClass(td, "k_edit_td_selected");
                this.selectedTdArray.push(td);
            }
        }
        for (let i = 0; i < tdArr.length; i++) {
            let td = tdArr[i];
            if (td !== this.movingTd && td !== this.clickedTd) {
                let rowSpan = $B.Dom.attr(td, "rowspan");
                let colSpan = $B.Dom.attr(td, "colspan");
                if (rowSpan || colSpan) {
                    if (rowSpan) {
                        let tmpV = parseInt($B.Dom.attr(td, "row")) + parseInt(rowSpan) - 1;
                        if (tmpV > maxRow) {
                            maxRow = tmpV;
                        }
                    }
                    if (colSpan) {
                        let tmpV = parseInt($B.Dom.attr(td, "col")) + parseInt(colSpan) - 1;
                        if (tmpV > maxCol) {
                            maxCol = tmpV;
                        }
                    }
                }
            }
        }
        if (maxRow !== endRow || maxCol !== endCol) {
            endRow = maxRow;
            endCol = maxCol;
            this.clearSelected();
            for (let i = 0; i < trs.length; i++) {
                if (i < startRow || i > endRow) {
                    continue;
                }
                let tds = trs[i].children;
                for (let j = 0; j < tds.length; j++) {
                    let td = tds[j];
                    let colIdx = parseInt($B.DomUtils.attribute(td, "col"));
                    if (colIdx < startCol || colIdx > endCol) {
                        continue;
                    }
                    $B.DomUtils.addClass(td, "k_edit_td_selected");
                    this.selectedTdArray.push(td);
                }
            }
        }
    }
    /**
     * 插入子表格时候适配 父单元格
     * ***/
    fit2parent(tableEl) {
        let $containTd = tableEl.parentNode.parentNode;
        if ($B.DomUtils.hasClass($containTd, "k_edit_input")) {
            return;
        }
        $containTd = $containTd.parentNode.parentNode;
        if ($containTd && $containTd.nodeName === "TD") {
            tableEl.style.width = "100%";
            tableEl.style.height = "100%";
            this.setWnHFromDom(tableEl);
            tableEl.style.width = "auto";
            tableEl.style.height = "auto";
        }
        return true;
    }
    /**
     * 提取dom里面的高度，宽度，并设置到td上
     * **/
    setWnHFromDom(tableEl) {
        this.foreachTd(tableEl, (td) => {
            this._updateTdSizeFromDom(td);
        });
        tableEl.style.width = "auto";
        tableEl.style.height = "auto";
    }
    /**
     * 提取Dom里面的高度，宽度更新行高度
     * ***/
    updateRowWnHFromDom(tr) {
        let tds = tr.children;
        for (let i = 0; i < tds.length; i++) {
            let td = tds[i];
            this._updateTdSizeFromDom(td);
        }
        let $pt = tr.parentNode.parentNode.parentNode.parentNode.parentNode;
        if ($pt.nodeName === "TD") { //多层嵌套
            this.updateRowWnHFromDom($pt.parentNode);
        }
    }
    _updateTdSizeFromDom(td) {
        let w = $B.DomUtils.width(td);
        let h = $B.DomUtils.height(td);
        let size = { width: w, height: h };
        let inW = $B.DomUtils.innerWidth(td);
        let inH = $B.DomUtils.innerHeight(td);
        $B.DomUtils.css(td.firstChild, { width: inW, height: inH });
        $B.DomUtils.css(td, size);
        $B.DomUtils.attribute(td, { w: w, h: h, iw: inW, ih: inH });
        if (td.firstChild.style.display === "none") {
            td.firstChild.style.display = "block";
        }
    }
    /**
     * 获取行里面合并单元格
     * **/
    _getRowspanTds(targetRow) {        
        var rowEndIdx = parseInt(targetRow.id.replace("row_", ""));
        var colRec = {};
        var prevRow = targetRow.previousSibling;
        while (prevRow) {
            let childs = prevRow.children;
            for (let i = 0, len = childs.length; i < len; ++i) {
                let td = childs[i];
                let index = $B.DomUtils.attribute(td, "col");
                let rowspan = $B.DomUtils.attribute(td, "rowspan");
                if (rowspan && !colRec[index]) {
                    let rowNum = parseInt($B.DomUtils.attribute(td, "row"));
                    let rowIdx = rowNum + parseInt(rowspan) - 1;
                    if (rowEndIdx <= rowIdx) {
                        colRec[index] = td;
                    }
                }
            }
            prevRow = prevRow.previousSibling;
        }
        return colRec;
    }
    /***
     * 判定td是否在嵌套表格内
     * **/
    isInnerTable(td) {
        let ret = false;
        let $pt = td.parentNode;
        let i = 6;
        while (i >= 0 && $pt) {
            if ($pt.nodeName === "TD") {
                ret = true;
                break;
            }
            $pt = $pt.parentNode;
            i--;
        }
        return ret;
    }
    /***
     * 清除嵌套子表格的周边边框，实现融合显示
     * ***/
    clear4border(tab) {
        let trs = tab.firstChild.children;
        let len = trs.length;
        let lastRow = len - 1;
        for (let i = 0; i < len; i++) {
            let tds = trs[i].children;
            for (let j = 0; j < tds.length; j++) {
                let td = tds[j];
                let notBorder = {};
                let go = false;
                if (i === 0) {//第一行
                    notBorder["border-top"] = "none";
                    if (!td.previousSibling) {
                        notBorder["border-left"] = "none";
                    }
                    if (!td.nextSibling) {
                        notBorder["border-right"] = "none";
                    }
                    if (i === lastRow) {
                        notBorder["border-bottom"] = "none";
                    }
                    go = true;
                } else if (i === lastRow) {
                    notBorder["border-bottom"] = "none";
                    if (!td.previousSibling) {
                        notBorder["border-left"] = "none";
                    }
                    if (!td.nextSibling) {
                        notBorder["border-right"] = "none";
                    }
                    go = true;
                } else {//中间行，需要判断是否rowspan
                    let rowspan = $B.DomUtils.attr(td, "rowspan");
                    if (rowspan) {
                        rowspan = parseInt(rowspan) - 1;
                        let rowIdx = i + rowspan;
                        if (rowIdx === lastRow) {
                            otBorder["border-bottom"] = "none";
                        }
                    }
                    if (!td.previousSibling) {
                        notBorder["border-left"] = "none";
                    }
                    if (!td.nextSibling) {
                        notBorder["border-right"] = "none";
                    }
                    go = true;
                }
                if (go) {
                    $B.DomUtils.css(td, notBorder);
                }
            }
        }
    }
    /**
     * 抽取td里面嵌套的表格,可能会有多层嵌套
     * ***/
    extractSubTables(td, tabArr, fn, deep) {
        if (!deep) {
            deep = 1;
        }
        let el = td.firstChild.firstChild.firstChild.firstChild;
        if (el && el.nodeName === "TABLE") {
            tabArr.push(el);
            if (fn) {
                let _break = fn(el, deep, td);
                if (_break) {
                    return;
                }
            }
            this.foreachTd(el, (td) => {
                this.extractSubTables(td, tabArr, fn, deep + 1);
            });
        }
    }
    /**
     * 根据偏移量调整列宽
     * **/
    updateColWidthByDiff(tabEL, ofsVal, lIdx, rIdx, ctrlKey) {
        let childTable = [];
        /**
         * 通过第一层嵌套来判断嵌套子表格位于左边还是右边
         * ***/
        let subPosLeft = false; //子表格位置是否位于左边
        let onGetSubTableFn = ($table, deep, prTd) => {
            $table.style.display = "none";
            if (ctrlKey) { //按下ctrl键，会影响整个子表格
                $table.style.width = "100%";
                $table.style.height = "100%";
            }
            let go = true;
            let idx = parseInt($B.DomUtils.attr(prTd, "col"));
            if (deep === 1) {
                let colspan = $B.DomUtils.attr(prTd, "colspan");
                if (colspan) {
                    idx = idx + parseInt(colspan) - 1;
                }
                subPosLeft = lIdx === idx;
            } else {
                if (subPosLeft) {
                    go = !prTd.nextSibling;
                } else {
                    go = !prTd.previousSibling;
                }
            }
            if (go) {
                this.foreachTd($table, (td, args) => {
                    if (ctrlKey) { //按下ctrl键，会影响整个子表格
                        td.firstChild.style.display = "none";
                        td.style.height = "auto";
                    } else {
                        let w, iw;
                        if (subPosLeft) { //左侧内置表格,修改最后一列的单元格宽度
                            if (args.islastCol) {
                                w = parseFloat($B.DomUtils.attr(td, "w")) + ofsVal;
                                iw = parseFloat($B.DomUtils.attr(td, "iw")) + ofsVal;
                                td.firstChild.style.width = iw + "px";
                                td.style.width = w + "px";
                            }
                        } else {//右侧内置表格，修改第一列的单元格宽度
                            if (args.colNum === 0) {
                                w = parseFloat($B.DomUtils.attr(td, "w")) - ofsVal;
                                iw = parseFloat($B.DomUtils.attr(td, "iw")) - ofsVal;
                                td.firstChild.style.width = iw + "px";
                                td.style.width = w + "px";
                            }
                        }
                    }
                });
            }
            $table.style.display = "";
            return !go;
        };
        let trs = tabEL.firstChild.children;
        for (let i = 0; i < trs.length; i++) {
            let tds = trs[i].children;
            for (let j = 0; j < tds.length; j++) {
                let _td = tds[j];
                let idx = parseInt($B.DomUtils.attr(_td, "col"));
                if (idx > rIdx) {
                    break;
                }
                let eidx = idx;
                let colspan = $B.DomUtils.attr(_td, "colspan");
                if (colspan) {
                    eidx = idx + parseInt(colspan) - 1;
                    if (lIdx === idx && eidx >= rIdx) {
                        break;
                    }
                }
                let w, iw, sbw;
                if (lIdx === idx || eidx === lIdx) { //右侧列
                    let old = $B.DomUtils.attr(_td, "w");
                    $B.DomUtils.attr(_td, { "oldw": old });
                    w = parseFloat(old) + ofsVal;
                    iw = parseFloat($B.DomUtils.attr(_td, "iw")) + ofsVal;
                    if (_td.nextSibling) {
                        sbw = parseFloat($B.DomUtils.attr(_td.nextSibling, "w")) - ofsVal;
                    }
                } else if (rIdx === idx) {//左侧列
                    w = parseFloat($B.DomUtils.attr(_td, "w")) - ofsVal;
                    iw = parseFloat($B.DomUtils.attr(_td, "iw")) - ofsVal;
                    if (_td.previousSibling) {
                        sbw = parseFloat($B.DomUtils.attr(_td.previousSibling, "oldw")) + ofsVal;
                        $B.DomUtils.removeAttr(_td.previousSibling, "oldw");
                    }
                }
                if (w < 8 || sbw < 8) { //不合法的调整
                    return;
                }
                if (w) {
                    $B.DomUtils.attr(_td, { "w": w, "iw": iw });
                    _td.firstChild.style.width = iw + "px";
                    _td.style.width = w + "px";
                    this.extractSubTables(_td, childTable, onGetSubTableFn);
                }
            }
        }
        setTimeout(() => {
            for (let i = 0; i < childTable.length; i++) {
                let $tb = childTable[i];
                this.setWnHFromDom($tb);
            }
        }, 1);
    }
    _setRowHeightByDiff(targetRow, topofs, skipTd, ctrlKey){
        //提取行里的rowspan单元格
        let rowspanTds = this._getRowspanTds(targetRow);
        let tds = targetRow.children;
        let childTable = [];
        //提取所有子表格
        let onGetSubTableFn = ($table, deep, prTd) => {
            $table.style.display = "none";
            if (ctrlKey) { //按下ctrl键，会影响整个子表格
                $table.style.width = "100%";
                $table.style.height = "100%";
            }
            let go = true;
            if (deep !== 1) {
                go = !prTd.parentNode.nextSibling;
            }
            if (go) {
                this.foreachTd($table, (td, args) => {
                    if (ctrlKey) { //按下ctrl键，会影响整个子表格
                        td.firstChild.style.display = "none";
                        td.style.height = "auto";
                    } else {
                        if (args.isLastRow) {
                            let h = parseFloat($B.DomUtils.attr(td, "h")) + topofs;
                            let ih = parseFloat($B.DomUtils.attr(td, "ih")) + topofs;
                            $B.DomUtils.attribute(td, { "h": h, "ih": ih });
                            td.firstChild.style.height = ih + "px";
                            td.style.height = h + "px";
                        }
                    }
                });
            }
            $table.style.display = "";
            return !go;
        };
        //更新目标行
        for (let i = 0; i < tds.length; i++) {
            let td = tds[i];
            let ih = parseFloat($B.DomUtils.attribute(td, "ih"));
            let h = parseFloat($B.DomUtils.attribute(td, "h"));
            let inHeight = ih + topofs;
            let height = h + topofs;
            if (height < this.minRowHeight) {
                topofs = this.minRowHeight - h;
                inHeight = ih + topofs;
                height = h + topofs;
            }
            if (!skipTd || td !== skipTd) {
                this.extractSubTables(td, childTable, onGetSubTableFn);
            }
            $B.DomUtils.attribute(td, { "h": height, "ih": inHeight });
            td.firstChild.style.height = inHeight + "px";
            td.style.height = height + "px";
        };
        //更新跨行单元格
        Object.keys(rowspanTds).forEach((key) => {
            let td = rowspanTds[key];
            if (!skipTd || td !== skipTd) {
                this.extractSubTables(td, childTable, onGetSubTableFn);
            }
            let height = parseFloat($B.DomUtils.attribute(td, "h")) + topofs;
            let inHeight = parseFloat($B.DomUtils.attribute(td, "ih")) + topofs;
            $B.DomUtils.attribute(td, { "h": height, "ih": inHeight });
            td.firstChild.style.height = inHeight + "px";
            td.style.height = height + "px";
        });
        //更新子嵌套表格
        for (let i = 0; i < childTable.length; i++) {
            let $tb = childTable[i];
            this.setWnHFromDom($tb);
        }
        return topofs;
    }
    /**
     * 根据偏移量更新行高
     * ***/
    updateRowHeightByDiff(targetRow, topofs, skipTd, ctrlKey) {
        topofs = this._setRowHeightByDiff(targetRow, topofs, skipTd, ctrlKey);
        let goUpdatePrt = true;
        if(ctrlKey){
            //更新相邻行
            let nextRow = targetRow.nextSibling;
            if(nextRow){
                goUpdatePrt = false;
                topofs = this._setRowHeightByDiff(nextRow, -topofs, undefined, ctrlKey);
            }            
        }
        if(goUpdatePrt){
            //父级嵌套高度调整
            let $ptab = this.getTableByTr(targetRow);
            let $wap = $ptab.parentNode.parentNode.parentNode;
            if ($B.DomUtils.hasClass($wap, "k_edit_td_wap")) {
                let $skipTd = $wap.parentNode;
                let $prtTR = $skipTd.parentNode;
                this.updateRowHeightByDiff($prtTR, topofs, $skipTd);
            }
        }       
        return topofs;
    }
    bindEventsExt(el){
        if(Array.isArray(el)){
            for(let i =0 ; i < el.length ;i++){
                this.bindEvents(el[i]);
                this.clearUIStyle(el[i]);
            }
        }else{
            if(el.tagName === "TABLE"){
                this.bindEvents(el);
                this.clearUIStyle(el);
            }else{
                let arr = $B.Dom.findByTagName(el,"table");
                for(let i = 0; i < arr.length ;i++){
                    this.bindEvents(arr[i]);
                    this.clearUIStyle(arr[i]);
                }
            }
        }
    }
    clearUIStyle(table){
        let trs = table.firstChild.children;
        for(let i =0 ;i < trs.length ;i++){
            let tds = trs[i].children;
            for(let j =0 ;j < tds.length ;j++){
                let td = tds[j];
                $B.Dom.removeClass(td,"k_edit_selected_td_shadow k_edit_td_selected");
                let $wap = td.firstChild.firstChild;
                let listp = $wap.children;
                if(listp.length === 1){
                    if(listp[0].firstChild.tagName === "TABLE"){
                        this.clearUIStyle(listp[0].firstChild);
                    }
                }
            }
        }
    }
    bindEvents(tableEl) {
        if (!tableEl.hasBindEvs) {
            tableEl.hasBindEvs = true;
            if (!this.tableEvents) {
                let tdPosCached = {};
                let splitXPos,
                    splitYPos,
                    targetRow;
                let getTdFn = function (el) {
                    while (el) {
                        if (el.nodeName === "TD") {
                            break;
                        }
                        el = el.parentNode;
                    }
                    return el;
                };
                this.tableEvents = {
                    mousedown: (e) => {
                        //_skip嵌套表格防止冒泡上层表格的监听处理 
                        let ev = e._e;
                        if (!ev._skip) {
                            ev._skip = true;
                            this.clearSelected();
                            UTILS.stopDefaultctxMenu();
                            let td = getTdFn(e.target);
                            let tabEL = this.getTableByTd(td);
                            this.setTarget(tabEL);
                            this.setClickTd(td);                            
                            if ((splitXPos || splitYPos) && e.which === 1) {
                                let prtEl = this.getRootPelByTable(tabEL);
                                let splitLine;
                                let dragOpt = {
                                    nameSpace: 'dragsplit', //命名空间，一个对象可以绑定多种拖动实现
                                    which: 1, //鼠标键码，是否左键,右键 才能触发拖动，默认左右键均可                                    
                                    axis: undefined, // v垂直方 h水平，默认全向                                      
                                    onDragReady: (e) => {//鼠标按下时候准备拖动前，返回true则往下执行，返回false则停止
                                    },
                                    onStartDrag: (e) => {//开始拖动事件
                                        this.dragging = true;
                                        this.editIns.makeUndoData(prtEl);
                                    },
                                    onDrag: (e) => {//拖动中事件
                                    },
                                    onStopDrag: (p) => {//拖动结束事件
                                        tdPosCached = {};
                                        $B.DomUtils.remove(p.state.target);
                                        setTimeout(() => {
                                            this.focusTd();
                                            this.dragging = false;
                                        }, 1);
                                        let data = p.state._data;
                                        if (data.topOffset !== 0) { //行拖动
                                            console.log("drag is end updateRow ....",p,targetRow);
                                            let topofs = this.updateRowHeightByDiff(targetRow, data.topOffset, undefined, p.e.ctrlKey);
                                            if (splitYPos) {
                                                splitYPos.top = splitYPos.top + topofs;
                                            }
                                        } else if (data.leftOffset !== 0) {//列拖动
                                            //console.log("列拖动 splitXPos ", splitXPos, data.leftOffset);
                                            let ofsVal = data.leftOffset;
                                            splitXPos.left = splitXPos.left + ofsVal;
                                            let lIdx = splitXPos.leftIdx;
                                            let rIdx = splitXPos.rightIdx;
                                            this.updateColWidthByDiff(tabEL, ofsVal, lIdx, rIdx, p.e.ctrlKey);
                                        }
                                        targetRow = undefined;
                                        if(Math.abs(data.topOffset) > 5 || Math.abs(data.leftOffset) > 5){
                                            this.editIns.putUndoData(1);
                                        }else{
                                            this.editIns.clearUndoingData();
                                        }
                                    },
                                    onMouseUp: (p) => {//当没有发生拖动，鼠标放开时候调用 
                                        tdPosCached = {};
                                        targetRow = undefined;
                                        splitYPos = undefined;
                                        $B.DomUtils.remove(p.state.target);
                                        setTimeout(() => {
                                            this.focusTd();
                                            this.dragging = false;
                                            this.editIns.clearUndoingData();
                                        }, 1);
                                    }
                                };
                                if (splitXPos) {
                                    dragOpt.cursor = "w-resize";
                                    dragOpt.axis = "h";
                                    let th = $B.DomUtils.height(tabEL);
                                    let top = $B.DomUtils.offset(tabEL).top;
                                    let bHeight = $B.DomUtils.height(document.body);
                                    let diff = bHeight - (top + th);
                                    let sliptHeight = th;
                                    if (diff < 1) {
                                        sliptHeight = sliptHeight + diff;
                                    }
                                    splitLine = $B.DomUtils.createEl("<div  style='cursor:w-resize;left:" + splitXPos.left + "px;top:" + top + "px;position:absolute;height:" + sliptHeight + "px;width:2px;border-left:1px solid #FF000D;z-index:99999999999'/>");
                                } else {
                                    let tw = $B.DomUtils.width(tabEL);
                                    dragOpt.axis = "v";
                                    dragOpt.cursor = "s-resize";
                                    splitYPos["left"] = $B.DomUtils.offset(tabEL).left;
                                    splitLine = $B.DomUtils.createEl("<div style='cursor:s-resize;left:" + splitYPos.left + "px;top:" + splitYPos.top + "px;position:absolute;height:3px;width:" + tw + "px;border-top:1px solid #FF000D;z-index:99999999999'/>");
                                }
                                if (splitLine) {
                                    this.dragging = true;
                                    $B.DomUtils.append(document.body, splitLine);
                                    $B.draggable(splitLine, dragOpt);
                                    $B.DomUtils.trigger(splitLine, "dragsplit.mousedown", {
                                        pageX: e.pageX,
                                        pageY: e.pageY,
                                        which: e.which
                                    });
                                }
                            } else {
                                this.mutilSelect = true;
                            }
                            setTimeout(() => {
                                ev._skip = undefined;
                            }, 1);
                        }
                    },
                    mouseup: (e) => {
                        if (!this.dragging) {
                            let ev = e._e;
                            if (!ev._skip) {
                                ev._skip = true;
                                //let td = getTdFn(e.target);
                                //let tabEL = this.getTableByTd(td);
                                splitXPos = undefined;
                                splitYPos = undefined;
                                this.mutilSelect = false;
                                this.movingTd = undefined;
                                setTimeout(() => {
                                    ev._skip = undefined;
                                }, 1);
                            }
                            let isSelected = this.selectedTdArray.length > 0;
                            if (isSelected || e.which === 3) {
                                this.showPanel(e);
                                setTimeout(() => {
                                    let cssMap = this.extractCss();
                                    this.editIns.reactiveTools(cssMap);
                                    this.reactPanel(cssMap);
                                }, 1);
                            }
                            if (isSelected) {
                                return false; //不触发文本的选区保存
                            }
                        }
                    },
                    mousemove: (e) => {
                        if (!this.dragging) {
                            //分割线功能检测是否靠近边线
                            let ev = e._e;
                            if (!ev._skip) {
                                ev._skip = true;
                                let td = getTdFn(e.target);
                                if (td) {
                                    let tabEL = this.getTableByTd(td);
                                    splitXPos = undefined;
                                    splitYPos = undefined;
                                    if (this.tableEl === tabEL) {
                                        let tdKey = this.getTdKey(td);
                                        let tabId = tabEL.id;
                                        let tabInfo = tdPosCached[tabId];
                                        if (!tabInfo) {
                                            let info = {};
                                            tdPosCached[tabId] = info;
                                            //用于判定嵌套表格是否是左右两侧拖动
                                            let tabOfs = $B.DomUtils.offset(tabEL);
                                            let tw = $B.DomUtils.outerWidth(tabEL);
                                            let th = $B.DomUtils.outerHeight(tabEL);
                                            info["x"] = tabOfs.left + 12;
                                            info["x1"] = tabOfs.left + tw - 12;
                                            info["y"] = tabOfs.top + 12;
                                            info["y1"] = tabOfs.top + th - 12;
                                            tabInfo = info;
                                        }
                                        if (this.mutilSelect) { //划选单元格                              
                                            if (!this.movingTd) {
                                                this.movingTd = td;
                                            } else {
                                                let movingId = $B.DomUtils.attribute(this.movingTd, "row") + "_" + $B.DomUtils.attribute(this.movingTd, "col");
                                                if (movingId !== tdKey) {
                                                    this.movingTd = td;
                                                    this.makeSelectedUi();
                                                    //清除document中的选择区域
                                                    this.editIns.clearDomSelected();
                                                    return false;
                                                }
                                            }
                                        } else {//普通移动，行列拖动
                                            let info = tdPosCached[tdKey];
                                            if (!info) {//采用缓存，避免每次都触发相同的计算
                                                info = {};
                                                tdPosCached[tdKey] = info;
                                                let ofs = $B.DomUtils.offset(td);
                                                let w = $B.DomUtils.outerWidth(td);
                                                let h = $B.DomUtils.outerHeight(td);
                                                info["left"] = ofs.left;
                                                info["top"] = ofs.top;
                                                info["w"] = w;
                                                info["h"] = h;
                                            }
                                            let mouseX = e.pageX;
                                            let mouseY = e.pageY;
                                            let startXshift = mouseX - info.left;
                                            let endXshift = info.left + info.w - mouseX;
                                            this.changeCursor("text");
                                            let nearVal = this.splitNearVal;
                                            if (startXshift <= nearVal || endXshift <= nearVal) {
                                                //嵌套表格右侧，左侧不可拖动
                                                let isInner = this.isInnerTable(td);
                                                let go = true;
                                                if (isInner) {
                                                    if (mouseX < tabInfo.x || mouseX > tabInfo.x1) {
                                                        go = false;
                                                    }
                                                }
                                                if (go) {
                                                    let tdIdx = parseInt($B.DomUtils.attr(td, "col"));
                                                    if (startXshift <= nearVal) {
                                                        splitXPos = { left: info.left, leftIdx: tdIdx - 1, rightIdx: tdIdx };
                                                    } else {
                                                        let colspan = $B.Dom.attr(td, "colspan");
                                                        if (colspan) {
                                                            tdIdx = tdIdx + parseInt(colspan) - 1;
                                                        }
                                                        splitXPos = { left: info.left + info.w, leftIdx: tdIdx, rightIdx: tdIdx + 1 };
                                                    }
                                                }
                                            }
                                            if (splitXPos) {
                                                this.changeCursor("w-resize");
                                            } else { //行高拖动                   
                                                let startYshift = mouseY - info.top;
                                                let endYshift = info.top + info.h - mouseY;
                                                if (startYshift <= nearVal || endYshift <= nearVal) {
                                                    let isInner = this.isInnerTable(td);
                                                    let go = true;
                                                    if (isInner) {
                                                        if (mouseY < tabInfo.y || mouseY > tabInfo.y1) {
                                                            go = false;
                                                        }
                                                    }
                                                    if (go) {
                                                        let currentRow = td.parentNode;
                                                        if (startYshift <= nearVal) {
                                                            targetRow = currentRow.previousSibling;
                                                            splitYPos = {
                                                                "top": info.top
                                                            };
                                                        } else {
                                                            splitYPos = {
                                                                "top": info.top + info.h
                                                            };
                                                            targetRow = currentRow;
                                                        }
                                                        this.changeCursor("s-resize");
                                                    }
                                                }
                                            }
                                        }
                                        setTimeout(() => {
                                            ev._skip = undefined;
                                        }, 1);
                                    } else {
                                        this.changeTableCursor(tabEL, "text");
                                    }
                                }
                            }
                        }
                    },
                    mouseenter: (e) => {
                        tdPosCached = {};
                        if (!this.dragging) {
                            splitXPos = undefined;
                            splitYPos = undefined;
                        }
                        if (this.selectedTdArray.length === 0) {
                            let tabEL = e.target;
                            this.setTarget(tabEL);
                        }
                        return false;
                    },
                    mouseleave: (e) => {
                        tdPosCached = {};
                        if (!this.dragging) {
                            splitXPos = undefined;
                            splitYPos = undefined;
                        }
                        return false;
                    }
                };
            }
            $B.DomUtils.bind(tableEl, this.tableEvents);
        }
    }
    hidePanel() {
        if (this.$panel) {
            this.$panel.style.display = "none";
            if (!this.holdColorCtl) {
                this.colorIns.hide();
            }
        }
        this.hideSubMenu();
    }
    hideSubMenu() {
        if (this.showSubMenu) {
            this.showSubMenu.style.display = "none";
        }
    }
    showPanel(pos) {
        if (!this.$panel) {
            let opts = {
                title: editCfg.label.tableEdit,
                onClosed: ($l) => {
                    this.hideSubMenu();
                },
                onCreated: ($b) => {
                    $B.DomUtils.append($b, editCfg.tablePropsForm);
                    this.initCtxMenu($b.firstChild);
                }
            };
            this.$panel = UTILS.createCommPanel(opts);
            this.editIns.bindFocusEv(this.$panel);
        }
        if (pos.pageX && pos.pageY) {
            pos = { left: pos.pageX + 14, top: pos.pageY + 14 };
        }
        let megerTR = $B.DomUtils.findbyId(this.$panel, "_split_merge_td_");
        if (this.selectedTdArray.length > 0) { //多选了单元格           
            megerTR.style.display = "";
            megerTR.lastChild.lastChild.innerText = editCfg.label.megerTd;
            $B.DomUtils.attr(megerTR, { "fn": "megerTd" });
        } else {
            let colspan = $B.DomUtils.attr(this.clickedTd, "colspan");
            let rowspan = $B.DomUtils.attr(this.clickedTd, "rowspan");
            if (colspan || rowspan) {
                megerTR.style.display = "";
                megerTR.lastChild.lastChild.innerText = editCfg.label.splitTd;
                $B.DomUtils.attr(megerTR, { "fn": "splitTd" });
            } else {
                megerTR.style.display = "none";
            }
        }
        UTILS.showPanel(this.$panel, pos);
    }
    /**
     * 联动面板
     * ***/
    reactPanel(graphCss) {
        let cssMap = {
            "border-top": undefined,
            "border-right": undefined,
            "border-bottom": undefined,
            "border-left": undefined,
            "background-color": undefined,
            "color": undefined,
            "text-align": undefined,
            "vertical-align": undefined
        };
        var cssSpanMap = UTILS.getSpanDefcss();
        var cssPelMap = UTILS.getPelDefCss();
        $B.extendObjectFn(cssMap, cssSpanMap);
        $B.extendObjectFn(cssMap, cssPelMap);
        if (this.selectedTdArray.length > 0) {
            for (let i = 0; i < this.selectedTdArray.length; i++) {
                this.extractTdcss(this.selectedTdArray[i], cssMap);
            }
        } else {
            this.extractTdcss(this.clickedTd, cssMap);
        }
        //console.log("reactPanel", cssMap);
        //对齐联动
        cssMap["text-align"] = graphCss["text-align"];
        let halign = "h_" + cssMap["text-align"];
        let valign = "v_" + cssMap["vertical-align"];
        let halignEl, valignEl;
        let childs = this.$AlignWap.children;
        for (let i = 0; i < childs.length; i++) {
            let el = childs[i];
            $B.DomUtils.removeClass(el, "activtd");
            if ($B.DomUtils.hasClass(el, halign)) {
                halignEl = el;
            } else if ($B.DomUtils.hasClass(el, valign)) {
                valignEl = el;
            }
        }
        $B.DomUtils.addClass(halignEl, "activtd");
        $B.DomUtils.addClass(valignEl, "activtd");

        //填充色
        let bColor = cssMap["background-color"];
        $B.DomUtils.css(this.$FillColor, { "background-color": bColor });

        $B.DomUtils.css(this.$fontColor, { "background-color": cssMap["color"] });

        //边框
        let $borderEl = this.$bodyPosWap.firstChild;
        let topTrue = this.changeBorderRectUI($borderEl, cssMap, "top");
        $borderEl = $borderEl.nextSibling;
        let rightTrue = this.changeBorderRectUI($borderEl, cssMap, "right");
        $borderEl = $borderEl.nextSibling;
        let bottomTrue = this.changeBorderRectUI($borderEl, cssMap, "bottom");
        $borderEl = $borderEl.nextSibling;
        let leftTrue = this.changeBorderRectUI($borderEl, cssMap, "left");
        this.$borderSizeInput.value = "1";
        let sizeList = this.$boderSizeOpt.children;
        let styleList = this.$boderStyleOpt.children;
        if (topTrue) {
            this.changeBorderRectOps(sizeList, styleList, cssMap, "top");
        }
        if (rightTrue) {
            this.changeBorderRectOps(sizeList, styleList, cssMap, "right");
        }
        if (bottomTrue) {
            this.changeBorderRectOps(sizeList, styleList, cssMap, "bottom");
        }
        if (leftTrue) {
            this.changeBorderRectOps(sizeList, styleList, cssMap, "left");
        }

        this.$megerSplitBtn.parentNode.parentNode.style.display = "none";
        if (this.isSelectedTds()) {
            this.$megerSplitBtn.innerText = editCfg.label.megerTd;
            this.$megerSplitBtn.parentNode.parentNode.style.display = "";
        } else {
            if (this.clickedTd) {
                let rspan = $B.DomUtils.attr(this.clickedTd, "rowspan");
                let cspan = $B.DomUtils.attr(this.clickedTd, "colspan");
                if (rspan || cspan) {
                    this.$megerSplitBtn.innerText = editCfg.label.splitTd;
                    this.$megerSplitBtn.parentNode.parentNode.style.display = "";
                }
            }
        }
    }
    changeBorderRectOps(sizeList, styleList, cssMap, name) {
        let valArr = cssMap["border-" + name].split("\s+");
        $B.DomUtils.css(this.$BorderColor, { "background-color": valArr[2] });
        for (let i = 0; i < sizeList.length; i++) {
            if (sizeList[i].value === valArr[0]) {
                sizeList[i].selected = true;
            } else {
                sizeList[i].selected = false;
            }
        }
        for (let i = 0; i < styleList.length; i++) {
            if (styleList[i].value === valArr[1]) {
                styleList[i].selected = true;
                this.$borderSizeInput.value = valArr[1].replace("px", "");
            } else {
                styleList[i].selected = false;
            }
        }
    }
    changeBorderRectUI($borderEl, cssMap, name) {
        let ret = false;
        if (this.isEmptyBorder(cssMap["border-" + name])) {
            $B.DomUtils.removeClass($borderEl, "activtd");
        } else {
            $B.DomUtils.addClass($borderEl, "activtd");
            return true;
        }
    }
    isEmptyBorder(css) {
        return !css || css === "" || css === "none" || editCfg.tableNoBorder === css;
    }
    extractTdcss(td, map) {
        let plist = td.firstChild.firstChild.children;
        let border = UTILS.getBorder(td);
        this._setBorder(border, map, "top");
        this._setBorder(border, map, "right");
        this._setBorder(border, map, "bottom");
        this._setBorder(border, map, "left");
        //字体颜色
        for (let i = 0; i < plist.length; i++) {
            UTILS.loopExtractCss(plist[i], map, true);
        }
        map["background-color"] = undefined;

        //背景色
        let bgColor = $B.DomUtils.css(td, "background-color");
        UTILS.setCssMapVal(map, { "background-color": bgColor }, "background-color");

        map["vertical-align"] = undefined;
        map["text-align"] = undefined;
        //对齐
        let vertical = $B.DomUtils.css(td, "vertical-align");
        UTILS.setCssMapVal(map, { "vertical-align": vertical }, "vertical-align");
        let textAlign = $B.DomUtils.css(td, "text-align");
        UTILS.setCssMapVal(map, { "text-align": textAlign }, "text-align");

    }
    _setBorder(border, map, key) {
        let name = "border-" + key;
        if (map[name] === undefined) {
            map[name] = border[name];
        } else if (map[name] !== null && map[name] !== border[name]) {
            map[name] = null;
        }
    }
    extractCss() {
        let cssSpanMap = UTILS.getSpanDefcss();
        let cssPelMap = UTILS.getPelDefCss();
        if (this.cssPelist.length > 0) {
            this.forPels(($p) => {
                UTILS.extractPcss($p, cssPelMap);
                let childs = $p.children;
                for (let i = 0; i < childs.length; i++) {
                    let $s = childs[i];
                    if ($s.nodeName === "SPAN") {
                        UTILS.extractSpancss($s, cssSpanMap);
                    }
                }
            });
        } else {
            this.foreachTdInnerPls(($p, $s, td) => {
                UTILS.extractPcss($p, cssPelMap);
                let childs = $p.children;
                for (let i = 0; i < childs.length; i++) {
                    let $s = childs[i];
                    if ($s.nodeName === "SPAN") {
                        UTILS.extractSpancss($s, cssSpanMap);
                    }
                }
            }, true);
        }
        let cssMap = $B.extendObjectFn(cssSpanMap, cssPelMap);
        return cssMap;
    }
    initCtxMenu($f) {
        let $wap = $B.DomUtils.findbyId($f, "_border_size_input");
        let $input = $B.DomUtils.createEl("<p style='padding:0px 0px;'><input style='width:58px;' type='text'/></p>");
        $B.createTextIfr($wap, $input);
        $input = $input.firstChild;//边框输入
        this.$borderSizeInput = $input;
        //修饰目标
        let $tg = $B.DomUtils.findbyId($f, "_target_table_1");
        this.css2TargetRadio = $tg;
        //边框位置
        let $bwap = $B.DomUtils.findbyId($f, "k_edit_border_wrap");
        this.$bodyPosWap = $bwap;
        $B.DomUtils.click($bwap, (e) => {
            if ($B.DomUtils.hasClass(e.target, "_border_it")) {
                if ($B.DomUtils.hasClass(e.target, "activtd")) {
                    $B.DomUtils.removeClass(e.target, "activtd");
                } else {
                    $B.DomUtils.addClass(e.target, "activtd");
                }
                this.borderFn();
            }
        });
        //边框大小
        $B.DomUtils.input($input, (e) => {
            this.borderFn();
        });
        let $sizeOPts = $B.DomUtils.findbyId($f, "_border_size_opts_");
        this.$boderSizeOpt = $sizeOPts;
        $B.DomUtils.change($sizeOPts, (e) => {
            $input.value = e.target.value.replace("px", "");
            setTimeout(() => { this.borderFn(); }, 1);
        });
        //边框类型
        let $bstye = $B.DomUtils.findbyId($f, "_border_style_opts_");
        this.$boderStyleOpt = $bstye;
        $B.DomUtils.change($bstye, (e) => {
            setTimeout(() => { this.borderFn(); }, 1);
        });
        //边框颜色
        let $bcolor = $B.DomUtils.findbyId($f, "_border_color_picker");
        this.$BorderColor = $bcolor;
        $B.DomUtils.click($bcolor, (e) => {
            let el = e.target;
            if (el.nodeName === "I") {
                el = el.parentNode;
            }
            if(this.colorIns.isShow() &&  el === this.colorIns.target){
                this.colorIns.hide();
            }else{
                let bgColor = $B.DomUtils.css(el, "background-color");
                this.colorIns._callFnKey = "tableColor";
                this.colorIns.setValue(bgColor, 1);
                this.colorIns.show(el);
                this.$colorEL = el;
                this.colorCaller = "borderFn";
            }
            return false;
        });

        //字体颜色 _font_color_picker _fill_color_picker
        let $fcolor = $B.DomUtils.findbyId($f, "_font_color_picker");
        this.$fontColor = $fcolor;
        $B.DomUtils.click($fcolor, (e) => {
            let el = e.target;
            if (el.nodeName === "I") {
                el = el.parentNode;
            }
            if(this.colorIns.isShow() &&  el === this.colorIns.target){
                this.colorIns.hide();
            }else{
                let bgColor = $B.DomUtils.css(el, "background-color");
                this.colorIns._callFnKey = "tableColor";
                this.colorIns.setValue(bgColor, 1);
                this.colorIns.show(el);
                this.$colorEL = el;
                this.colorCaller = "fontColorFn";
            }            
            return false;
        });

        //填充颜色
        let $fillcolor = $B.DomUtils.findbyId($f, "_fill_color_picker");
        this.$FillColor = $fillcolor;
        $B.DomUtils.click($fillcolor, (e) => {
            let el = e.target;
            if (el.nodeName === "I") {
                el = el.parentNode;
            }
            if(this.colorIns.isShow() &&  el === this.colorIns.target ){
                this.colorIns.hide();
            }else{
                let bgColor = $B.DomUtils.css(el, "background-color");
                this.colorIns._callFnKey = "tableColor";
                this.colorIns.setValue(bgColor, 1);
                this.colorIns.show(el);
                this.$colorEL = el;
                this.colorCaller = "backgroundColorFn";
            }
            return false;
        });

        //对齐
        let $align = $B.DomUtils.findbyId($f, "_table_align");
        $B.DomUtils.click($align, (e) => {
            let el = e.target;
            let clz = "_h";
            if (el.nodeName === "I") {
                el = el.parentNode;
            }
            if ($B.DomUtils.hasClass(el, "_v")) {
                clz = "_v";
            }
            let prevs = el.previousSibling;
            let nexts = el.nextSibling;
            while (prevs) {
                if ($B.DomUtils.hasClass(prevs, clz)) {
                    $B.DomUtils.removeClass(prevs, "activtd");
                }
                prevs = prevs.previousSibling;
            }
            while (nexts) {
                if ($B.DomUtils.hasClass(nexts, clz)) {
                    $B.DomUtils.removeClass(nexts, "activtd");
                }
                nexts = nexts.nextSibling;
            }
            if (el.nodeName === "DIV") {
                if ($B.DomUtils.hasClass(el, "activtd")) {
                    $B.DomUtils.removeClass(el, "activtd");
                } else {
                    $B.DomUtils.addClass(el, "activtd");
                }
            }
            if (clz === "_h") {
                if ($B.Dom.hasClass(el, "h_center")) {
                    let btn = this.editIns.toolIns ? this.editIns.toolIns.btnElMap["alignCenterFn"] : undefined;
                    this.alignCenterFn(undefined, btn);
                } else if ($B.Dom.hasClass(el, "h_right")) {
                    let btn = this.editIns.toolIns ? this.editIns.toolIns.btnElMap["alignRightFn"] : undefined;
                    this.alignRightFn(undefined, btn);
                } else if ($B.Dom.hasClass(el, "h_left")) {
                    let btn = this.editIns.toolIns ? this.editIns.toolIns.btnElMap["alignLeftFn"] : undefined;
                    this.alignLeftFn(undefined, btn);
                }
            } else {
                if ($B.Dom.hasClass(el, "v_top")) {
                    this.vAlignTop();
                } else if ($B.Dom.hasClass(el, "v_middle")) {
                    this.vAlignMiddel();
                } else if ($B.Dom.hasClass(el, "v_bottom")) {
                    this.vAlignBottom();
                }
            }
        });
        this.$AlignWap = $align;

        //插入,删除
        let $insertNode = $B.DomUtils.findbyId($f, "_insert_op_tr");
        let $deleteNode = $B.DomUtils.findbyId($f, "_delete_op_tr");
        let events = {
            mouseenter: (e) => {
                let el = e.target;
                let id = el.id;
                if (!this[id]) {
                    this[id] = UTILS.createChildCtxMenu(id, editCfg.tableCtx[id], (fn, params) => {                      
                        if (typeof this[fn] === "function") {
                            this[fn](params);
                        } else {
                            console.log(fn + " is not found!");
                        }
                    });
                }
                if (this.showSubMenu && this.showSubMenu !== this[id]) {
                    this.hideSubMenu();
                }
                UTILS.showCtxMenu(this[id], el);
                this.showSubMenu = this[id];
            }
        };
        $B.DomUtils.bind($insertNode, events);
        $B.DomUtils.bind($deleteNode, events);

        let hideFn = (e) => {
            this.hideSubMenu();
        };
        $B.DomUtils.mouseenter($insertNode.previousSibling, hideFn);
        $B.DomUtils.mouseenter($deleteNode.nextSibling, hideFn);

        //段落设置
        let $graph = $deleteNode.nextSibling;
        $B.Dom.click($graph, (e) => {
            //console.log("open graph........................",this.$panel.lastChild.lastChild);
            this.$panel.lastChild.lastChild.openFlag = 'table';;
            let $fb = this.editIns.toolIns.paragraphFnMaker("paragraphFn", this.$panel.lastChild.lastChild);
            this.hidePanel();
            let cssMap = this.extractCss();
            this.editIns.toolIns.rectiveGraphUI($fb, cssMap);
        });
        //拆分合并
        $B.DomUtils.click($graph.nextSibling, (e) => {
            let el = e.target;
            if (el.nodeName === "TR") {
                el = el.firstChild.lastChild;
            } else {
                while (el) {
                    if (el.nodeName === "TD") {
                        break;
                    }
                    el = el.parentNode;
                }
                el = el.lastChild;
            }
            let lable = el.innerText;
            if (lable === editCfg.label.megerTd) {
                this.megerTd();
            } else {
                this.splitTd();
            }
            this.hidePanel();
        });
        this.$megerSplitBtn = $graph.nextSibling.lastChild.lastChild;
    }
    borderFn() {
        let borderCss = {};
        let childs = this.$bodyPosWap.children;
        for (let i = 0; i < childs.length; i++) {
            if ($B.DomUtils.hasClass(childs[i], "activtd")) {
                borderCss[$B.DomUtils.attr(childs[i], "tg")] = undefined;
            }
        }
        let size = this.$borderSizeInput.value;
        if (size === "") {
            size = this.$boderSizeOpt.value;
        } else {
            size = size + "px";
        }
        let style = this.$boderStyleOpt.value;
        let color = $B.DomUtils.css(this.$BorderColor, "background-color");
        let keys = Object.keys(borderCss);
        for (let i = 0; i < keys.length; i++) {
            borderCss[keys[i]] = size + " " + style + " " + color;
        }
        let isTable = $B.DomUtils.attr(this.css2TargetRadio, "checked");
        if (isTable) { //表格修饰
            let rowNum = parseInt($B.DomUtils.attr(this.tableEl, "row")) - 1;
            this.foreachTd(this.tableEl, (td, args) => {
                let newCss = {};
                let go = false;
                if (!td.previousSibling) {
                    if (borderCss["border-left"]) {
                        newCss["border-left"] = borderCss["border-left"];
                        go = true;
                    } else {
                        this.removeTdSomeBorder(td, "left");
                    }
                }
                if (!td.nextSibling) {
                    if (borderCss["border-right"]) {
                        newCss["border-right"] = borderCss["border-right"];
                        go = true;
                    } else {
                        this.removeTdSomeBorder(td, "right");
                    }
                }
                if (args.rowNum === 0) {
                    if (borderCss["border-top"]) {
                        newCss["border-top"] = borderCss["border-top"];
                        go = true;
                    } else {
                        this.removeTdSomeBorder(td, "top");
                    }
                }
                let rowspan = $B.DomUtils.attr(td, "rowspan");
                if (rowspan) {
                    let endRow = args.rowNum + parseInt(rowspan) - 1;
                    rowspan = endRow === rowNum;
                }
                if (args.rowNum === rowNum || rowspan) {
                    if (borderCss["border-bottom"]) {
                        newCss["border-bottom"] = borderCss["border-bottom"];
                        go = true;
                    } else {
                        this.removeTdSomeBorder(td, "bottom");
                    }
                }
                if (go) {
                    console.log(td, newCss);
                    this.updateTdBorder(td, newCss);
                }
            });
        } else {
            if (this.isSelectedTds()) {
                for (let i = 0; i < this.selectedTdArray.length; ++i) {
                    let td = this.selectedTdArray[i];
                    this.updateTdBorder(td, borderCss);
                    this.css2Siblings(td);
                }
            } else {
                this.updateTdBorder(this.clickedTd, borderCss);
                this.css2Siblings(this.clickedTd);
            }
        }
    }
    updateTdBorder(td, borderCss) {
        let cssObj = this.getNotBorderStyle(td);
        $B.extendObjectFn(cssObj, borderCss);
        let style = $B.cssObj2string(cssObj);
        $B.DomUtils.attr(td, { style: style });
    }
    getNotBorderStyle(td) {
        let cssObj = $B.style2cssObj(td);
        let keys = Object.keys(cssObj);
        for (let i = 0; i < keys.length; ++i) {
            let key = keys[i];
            if (key.indexOf("border") > -1) {
                delete cssObj[key];
            }
        }
        return cssObj;
    }
    css2Siblings(td) {
        var prevTd = td.previousSibling;
        var nextTd = td.nextSibling;
        var idx = parseInt($B.Dom.attr(td,"col"));
        if(prevTd){
            let prevIdx =  parseInt($B.Dom.attr(prevTd,"col")) + 1;
            if(prevIdx !== idx){
                prevTd = undefined;
            }
        }
        if(nextTd){
            let nextIdx =  parseInt($B.Dom.attr(nextTd,"col")) - 1;
            if(nextIdx !== idx){
                nextTd = undefined;
            }
        }
        var row = td.parentNode;
        var prevRow = row.previousSibling;
        var nextRow = row.nextSibling;
        var bodyObj = UTILS.getBorder(td);
        var borderTop = bodyObj["border-top"];
        var borderRight = bodyObj["border-right"];
        var borderBottom = bodyObj["border-bottom"];
        var borderLeft = bodyObj["border-left"];
        if (this.isEmptyBorder(borderTop)) {
            borderTop = undefined;
        }
        if (this.isEmptyBorder(borderRight)) {
            borderRight = undefined;
        }
        if (this.isEmptyBorder(borderBottom)) {
            borderBottom = undefined;
        }
        if (this.isEmptyBorder(borderLeft)) {
            borderLeft = undefined;
        }
        if (nextTd) {
            if (borderRight) {
                $B.DomUtils.css(nextTd, { "border-left": borderRight });
            } else {
                this.removeTdSomeBorder(nextTd, "left");
            }
        }
        if (prevTd) {
            if (borderLeft) {
                $B.DomUtils.css(prevTd, { "border-right": borderLeft });
            } else {
                this.removeTdSomeBorder(prevTd, "right");
            }
        }
        var index = parseInt($B.DomUtils.attr(td, "col"));
        if (prevRow) {
            let tds = prevRow.children
            for (let i = 0; i < tds.length; i++) {
                let _td = tds[i];
                let colspan = $B.DomUtils.attr(_td, "colspan");
                let idx = parseInt($B.DomUtils.attr(_td, "col"));
                if (!colspan) {
                    if (index === idx) {
                        if (borderTop) {
                            $B.DomUtils.css(_td, { "border-bottom": borderTop });
                        } else {
                            this.removeTdSomeBorder(_td, "bottom");
                        }
                        break;
                    }
                }
                if (idx > index) {
                    break;
                }
            }
        }
        if (nextRow && borderBottom) {
            let tds = nextRow.children
            for (let i = 0; i < tds.length; i++) {
                let _td = tds[i];
                let colspan = $B.DomUtils.attr(_td, "colspan");
                let idx = parseInt($B.DomUtils.attr(_td, "col"));
                if (!colspan) {
                    if (index === idx) {
                        if (borderBottom) {
                            $B.DomUtils.css(_td, { "border-top": borderBottom });
                        } else {
                            this.removeTdSomeBorder(_td, "top");
                        }
                        break;
                    }
                }
                if (idx > index) {
                    break;
                }
            }
        }
    }
    removeTdSomeBorder(_td, delBorder) {
        let borderObj = UTILS.getBorder(_td, delBorder);
        let cssObj = this.getNotBorderStyle(_td);
        $B.extendObjectFn(cssObj, borderObj);
        let style = $B.cssObj2string(cssObj);
        $B.DomUtils.attr(_td, { style: style });
    }
    makeUndoRec(el){
        let $p;
        if(el.tagName === "TABLE"){
            $p = this.getRootPelByTable(el);
        }else{
            $p = this.getRootPelByTd(el);
        }        
        this.editIns.makeUndoData($p);
        this.editIns.putUndoData(1);
    }
    splitTd() {
        this.makeUndoRec(this.clickedTd);
        let colspan = parseInt($B.Dom.attr(this.clickedTd, "colspan"));
        let rowCount = parseInt($B.Dom.attr(this.clickedTd, "rowspan")) - 1;
        let col = parseInt($B.Dom.attr(this.clickedTd, "col"));
        let row = parseInt($B.Dom.attr(this.clickedTd, "row"));
        let tdWidth = parseFloat($B.Dom.attr(this.clickedTd, "w"));
        let td;
        let copyStyle = $B.style2cssObj(this.clickedTd);
        delete copyStyle.width;
        delete copyStyle.height;
        let avgWidth;
        let isNolyRow = this.tableEl.firstChild.children.length === 1;
        if (colspan) {
            colspan = parseInt(colspan);
            avgWidth = tdWidth / colspan;
            if (isNolyRow) {
                copyStyle.width = avgWidth + "px";
            }
            this.clickedTd.style.width = avgWidth + "px";
            this.clickedTd.firstChild.style.width = "auto";
            $B.Dom.removeAttr(this.clickedTd, "colspan");
            let count = colspan - 1;
            let curCol = col;
            let insertTarget = this.clickedTd;
            while (count > 0) {
                curCol = curCol + 1;
                td = Table.createTD({
                    "tabindex": "0",
                    "row": row,
                    "col": curCol
                }, copyStyle);
                count = --count;
                $B.Dom.after(insertTarget, td);
                insertTarget = td;
            }
        }
        if (rowCount) {
            let tdCount = 1; //需要创建的td数量
            if (colspan) {
                tdCount = colspan;
            }
            if (!avgWidth) {
                avgWidth = tdWidth;
                if (isNolyRow) {
                    copyStyle.width = avgWidth + "px";
                }
            }
            this.clickedTd.style.width = avgWidth + "px";
            this.clickedTd.style.height = "auto";
            this.clickedTd.firstChild.style.height = "auto";
            $B.Dom.removeAttr(this.clickedTd, "rowspan");
            let tdRow = this.clickedTd.parentNode;
            let currentRow = tdRow.nextSibling;
            let curRow = row;
            while (rowCount > 0) {
                curRow = curRow + 1;
                if (!currentRow) {
                    currentRow = Table.createTR({
                        "id": "row_" + curRow
                    });
                    $B.Dom.append(this.tableEl.firstChild, currentRow);
                }
                let targetTd, index, helper, count, colIdx;
                let childArray = currentRow.children;
                let len = childArray.length;
                if (len === 0) {
                    len = 1;
                }
                for (let i = 0; i < len; ++i) {
                    targetTd = undefined;
                    if (childArray.length === 0) {
                        targetTd = 1;
                    } else {
                        td = childArray[i];
                        index = parseInt($B.Dom.attr(td, "col"));
                        if (index >= col) {
                            if (td.previousSibling) {
                                targetTd = td.previousSibling;
                            } else {
                                targetTd = 1;
                            }
                        } else if (!td.nextSibling) {
                            targetTd = td;
                        }
                    }
                    if (targetTd) {
                        helper = 0;
                        count = tdCount;
                        if (targetTd === 1) {
                            colIdx = -1;
                        } else {
                            colIdx = parseInt($B.Dom.attr(targetTd, "col"));
                        }
                        while (count > 0) {
                            colIdx++;
                            td = Table.createTD({
                                "tabindex": "0",
                                "row": curRow,
                                "col": colIdx
                            }, copyStyle);
                            td.style.width = avgWidth + "px";
                            td.style.height = "auto";
                            if (targetTd === 1) {
                                $B.Dom.prepend(currentRow, td);
                            } else {
                                $B.Dom.after(targetTd, td);
                            }
                            targetTd = td;
                            count = --count;
                        }
                        break;
                    }
                }
                currentRow = currentRow.nextSibling;
                rowCount = --rowCount;
            }
        }
        this.setWnHFromDom(this.tableEl);
    }
    megerTd() {
        console.log("megerTd go.........");
        let rowspan = 0,
            colspan = 0,
            modifyTd, //需要合并到的单元格
            rowSet = new Set(), //合并的行号
            colSet = new Set(); //合并的列号
        this.foreachSeletedTds(function (td) {
            let row = parseInt($B.DomUtils.attr(td, "row"));
            let col = parseInt($B.DomUtils.attr(td, "col"));
            //找到待合并的单元格
            if (!modifyTd) {
                modifyTd = td;
            } else {
                let r = parseInt($B.DomUtils.attr(modifyTd, "row"));
                if (row < r) {
                    modifyTd = td;
                } else if (r === row) {
                    let l = parseInt($B.DomUtils.attr(modifyTd, "col"));
                    if (col < l) {
                        modifyTd = td;
                    }
                }
            }
            //被合并的行号
            rowSet.add(row);
            rowspan = $B.DomUtils.attr(td, "rowspan");
            if (rowspan) {
                rowspan = parseInt(rowspan) - 1;
                let r = row;
                while (rowspan > 0) {
                    r++;
                    rowSet.add(r);
                    rowspan--;
                }
            }
            colSet.add(col);
            colspan = $B.DomUtils.attr(td, "colspan");
            if (colspan) {
                colspan = parseInt(colspan) - 1;
                let r = col;
                while (colspan > 0) {
                    r++;
                    colSet.add(r);
                    colspan--;
                }
            }
        });
        if (modifyTd) {
            this.makeUndoRec(modifyTd);
            rowspan = rowSet.size;
            colspan = colSet.size;
            let rowMap = {};
            let rHMap = {};
            let tabWidth = $B.Dom.width(this.tableEl.firstChild);
            let megerColMap = {};
            let megerColWidthMap = {};
            let rmTdArr = [];
            this.foreachSeletedTds(function (td) {
                if (td !== modifyTd) {
                    let rowspan = $B.Dom.attr(td, "rowspan");
                    let l = $B.Dom.attr(td, "col");
                    let r = $B.Dom.attr(td, "row");
                    if (megerColMap[l]) {
                        if (rowspan) {
                            megerColMap[l] = megerColMap[l] + parseInt(rowspan);
                        } else {
                            megerColMap[l] = megerColMap[l] + 1;
                        }
                    } else {
                        if (rowspan) {
                            megerColMap[l] = parseInt(rowspan);
                        } else {
                            megerColMap[l] = 1;
                        }
                    }
                    if (!rowMap[r]) {
                        rowMap[r] = td.parentNode;
                        let h = $B.Dom.height(td.parentNode);
                        rHMap[r] = h;
                    }
                    let tmpW = $B.Dom.width(td);
                    if (megerColWidthMap[l]) {
                        if (megerColWidthMap[l] > tmpW) {
                            megerColWidthMap[l] = tmpW;
                        }
                    } else {
                        megerColWidthMap[l] = tmpW;
                    }
                    rmTdArr.push(td);
                }
            });
            for (let i = 0; i < rmTdArr.length; i++) {
                $B.Dom.remove(rmTdArr[i]);
            }
            let allHeight = $B.Dom.height(modifyTd.parentNode);
            Object.keys(rowMap).forEach((key) => {
                let tr = rowMap[key];
                if (tr.children.length === 0) {
                    tr.parentNode.removeChild(tr);
                    allHeight = allHeight + rHMap[key];
                }
            });
            if (rowspan > 1 || colspan > 1) {
                let newAttr = {};
                if (rowspan > 1) {
                    newAttr["rowspan"] = rowspan;
                }
                if (colspan > 1) {
                    newAttr["colspan"] = colspan;
                }
                $B.Dom.attr(modifyTd, newAttr);
                //先判断是否是全表合并
                let $tboy = this.tableEl.firstChild;
                if ($tboy.children.length === 1 && $tboy.children[0].children.length === 1) {
                    modifyTd.style.width = tabWidth + "px";
                    modifyTd.style.height = allHeight + "px";
                } else {
                    let rowNum = parseInt($B.Dom.attr(this.tableEl, "row"));
                    //是否是整列删除
                    let diffWidth = 0;
                    Object.keys(megerColMap).forEach((key) => {
                        if (megerColMap[key] === rowNum) {
                            diffWidth = diffWidth + megerColWidthMap[key];
                        }
                    });
                    if (diffWidth > 0) {
                        let tdWidth = $B.Dom.width(modifyTd);
                        modifyTd.style.width = tdWidth + diffWidth + "px";
                    }
                }
                this._updateTdSizeFromDom(modifyTd);
            }
            this.hidePanel();
            this.clearSelected();
            this.setClickTd(modifyTd);
        }
    }
    insertRight() {
        this.insertColFn("r");
    }
    insertLeft() {
        this.insertColFn("l");
    }
    /**
     * l左侧插入列  
     * r右侧插入列
     * **/
    insertColFn(prs) {
        this.hidePanel();
        //console.log("insertColFn insertColFn insertColFn-----> ", prs);
        this.makeUndoRec(this.clickedTd);
        let col = parseInt($B.Dom.attr(this.clickedTd, "col"));
        let endCol = col;
        let sp = $B.Dom.attr(this.clickedTd, "colspan");
        if (sp) {
            endCol = col + parseInt(sp) - 1;
        }
        let trs = this.tableEl.firstChild.children;
        let colSubTableCouter = {};
        for (let i = 0; i < trs.length; i++) {
            let tr = trs[i];
            let tds = tr.children;
            for (let j = 0; j < tds.length; j++) {
                let td = tds[j];
                let col = $B.Dom.attr(td, "col");
                let colspan = $B.Dom.attr(td, "colspan");
                let tableCOUnt = 0;
                if (td.firstChild.firstChild.firstChild.firstChild.tagName === "TABLE") {
                    tableCOUnt = 1;
                }
                if (colspan) {
                    let endCol = parseInt(col) + parseInt(colspan) - 1;
                    if (!colSubTableCouter[endCol]) {
                        colSubTableCouter[endCol] = tableCOUnt;
                    }
                }
                if (!colSubTableCouter[col]) {
                    colSubTableCouter[col] = tableCOUnt;
                }
            }
        }
        let newCol, need2fixLastTd;
        if (prs === "l") {
            newCol = col;
        } else {
            newCol = col + 1;
            if (endCol === col && !this.clickedTd.nextSibling) {
                need2fixLastTd = true;
            }
        }
        for (let i = 0; i < trs.length; i++) {
            let tr = trs[i];
            let tds = tr.children;
            for (let j = 0; j < tds.length; j++) {
                let td = tds[j];
                let style = $B.style2cssObj(td); // $B.Dom.attr(td,"style") ;
                let idx = parseInt($B.Dom.attr(td, "col"));
                let row = parseInt($B.Dom.attr(td, "row"));
                let endIdx = idx;
                let colspan = $B.Dom.attr(td, "colspan");
                if (colspan) {
                    endIdx = idx + parseInt(colspan) - 1;
                }
                if (prs === "l") { //左侧插入
                    if (newCol === 0) {
                        this.insertingMakeTd(prs, td, colSubTableCouter, row, newCol, style, "before");
                        break;
                    }
                    if (idx === col) {
                        this.insertingMakeTd(prs, td, colSubTableCouter, row, newCol, style, "before");
                        break;
                    }
                    if (colspan && col >= idx && col <= endIdx) {
                        $B.Dom.attr(td, { "colspan": parseInt(colspan) + 1 });
                        this.colIndxAdd1(td.nextSibling);
                        break;
                    }
                    if (idx > col) {
                        if ((idx - 1) === newCol) {
                            this.insertingMakeTd(prs, td, colSubTableCouter, row, newCol, style, "before");
                            break;
                        }
                        if (td.previousSibling) {
                            let prevTd = td.previousSibling;
                            let prevIdx = parseInt($B.Dom.attr(prevTd, "col"));
                            let span = $B.Dom.attr(prevTd, "colspan");
                            if (span) {
                                prevIdx = prevIdx + parseInt(span) - 1;
                            }
                            if ((prevIdx + 1) === newCol) {
                                this.insertingMakeTd(prs, prevTd, colSubTableCouter, row, newCol, style, "after");
                                break;
                            }
                        }
                        this.colIndxAdd1(td);
                        break;
                    }
                    if (idx < col && !td.nextSibling) {
                        let tmp = col - 1;
                        if (endIdx === tmp) {
                            this.insertingMakeTd(prs, td, colSubTableCouter, row, newCol, style, "after");
                            break;
                        }
                    }
                } else { //右边插入
                    if (endIdx === col) {
                        this.insertingMakeTd(prs, td, colSubTableCouter, row, newCol, style, "after");
                        break;
                    }
                    if (colspan && idx <= col && endIdx >= col) {
                        this.updateColSpan(colspan, td);
                        break;
                    }
                    if (idx > col) {
                        if (newCol === idx) {
                            this.insertingMakeTd(prs, td, colSubTableCouter, row, newCol, style, "before");
                            break;
                        }
                        this.colIndxAdd1(td);
                        break;
                    }
                    if (idx < col) {
                        if (!td.nextSibling && need2fixLastTd) {
                            this.insertingMakeTd(prs, td, colSubTableCouter, row, newCol, style, "after");
                            break;
                        }
                    }

                }
            }
        }
        this.setWnHFromDom(this.tableEl);
        let colNum = parseInt($B.Dom.attr(this.tableEl, "col")) + 1;
        $B.Dom.attr(this.tableEl, { "col": colNum });
    }
    insertingMakeTd(prs, targetId, colSubTableCouter, row, newCol, style, actionName) {
        let colWidth = this.modifySibligTdWidth(prs, targetId, colSubTableCouter);
        if (colWidth === 0) {
            colWidth = 66; //撑开整个表格
        }
        style.width = colWidth + "px";
        style.height = "auto";
        let newTd = Table.createTD({
            row: row,
            col: newCol
        }, style);
        $B.Dom[actionName](targetId, newTd);
        this.colIndxAdd1(newTd.nextSibling);
    }
    colIndxAdd1(td) {
        while (td) {
            let nCol = parseInt($B.Dom.attr(td, "col")) + 1;
            $B.Dom.attr(td, { "col": nCol });
           // td.firstChild.firstChild.firstChild.firstChild.innerText = nCol;
            td = td.nextSibling;
        }
    }
    updateColSpan(colspan, td) {
        colspan = parseInt(colspan) + 1;
        $B.Dom.attr(td, { colspan: colspan });
        let nextTd = td.nextSibling;
        if (nextTd) {
            this.colIndxAdd1(nextTd);
        }
    }
    /**
     * 如果该列对应的单元格存在嵌套表格，则不做出让
     * **/
    modifySibligTdWidth(flag, td, counter) {
        let avliWidth = 0;
        //列宽大于40才能出让
        let preEl = flag === "l" ? td.previousSibling : td;
        let nextEl = flag === "l" ? td : td.nextSibling;
        while (preEl) {
            let col = $B.Dom.attr(preEl, "col");
            if (counter[col] === 0) {
                let w = parseFloat($B.Dom.attr(preEl, "w"));
                if (w > 40) {
                    if (nextEl) {
                        avliWidth = w / 4;
                        w = w - avliWidth;
                    } else {
                        avliWidth = w / 2;
                        w = avliWidth;
                    }
                    preEl.firstChild.style.width = (w - 1) + "px";
                    preEl.style.width = w + "px";
                    break;
                }
            }
            preEl = preEl.previousSibling;
        }
        while (nextEl) {
            let col = $B.Dom.attr(nextEl, "col");
            if (counter[col] === 0) {
                let w = parseFloat($B.Dom.attr(nextEl, "w"));
                if (w > 40) {
                    let haftw;
                    if (avliWidth > 0) {
                        haftw = w / 4;
                        w = w - haftw;
                    } else {
                        haftw = w / 2;
                        w = haftw;
                    }
                    nextEl.firstChild.style.width = (w - 1) + "px";
                    nextEl.style.width = w + "px";
                    avliWidth = avliWidth + haftw;
                    break;
                }
            }
            nextEl = nextEl.nextSibling;
        }
        return avliWidth;
    }
    insertUp() {
        this.insertRowFn("t");
    }
    insertDown() {
        this.insertRowFn("d");
    }
    insertRowFn(prs) {
        this.hidePanel();
        this.makeUndoRec(this.clickedTd);
        var currentRow = this.clickedTd.parentNode;
        var rowIdx = parseInt($B.Dom.attr(this.clickedTd, "row"));
        var newTr = Table.createTR();
        var newTd;
        if (prs === "t") { //上方插入
            $B.Dom.attr(newTr, { "id": "row_" + rowIdx });
            $B.Dom.before(currentRow, newTr);
        } else {
            let rowspan = $B.Dom.attr(this.clickedTd, "rowspan");
            if (rowspan) {
                rowspan = parseInt(rowspan) - 1;
                while (rowspan > 0) {
                    currentRow = currentRow.nextSibling;
                    rowspan--;
                }
                rowIdx = parseInt($B.Dom.attr(currentRow, "id").replace("row_", ""));
            }
            rowIdx++;
            $B.Dom.attr(newTr, { "id": "row_" + rowIdx });
            $B.Dom.after(currentRow, newTr);
        }
        var currentRowIndex = rowIdx;
        /***更新后面的id行号***/
        var nextRow = newTr.nextSibling;
        while (nextRow) {
            rowIdx++;
            $B.Dom.attr(nextRow, { "id": "row_" + rowIdx });
            let childs = nextRow.children;
            for (let i = 0; i < childs.length; i++) {
                $B.Dom.attr(childs[i], { "row": rowIdx });
            }
            nextRow = nextRow.nextSibling;
        }
        //分析需要插入多少个td,提前需要rowspan+1的单元格
        var prevRow = newTr.previousSibling;
        var rowspanTds = [];
        var notCreateTd = {};
        var td, rspan;
        while (prevRow) {
            let ridx = parseInt($B.Dom.attr(prevRow, "id").replace("row_", ""));
            let childs = prevRow.children;
            for (let i = 0, len = childs.length; i < len; ++i) {
                td = childs[i];
                let tdIdx = parseInt($B.Dom.attr(td, "col"));
                if (!notCreateTd[tdIdx]) {
                    rspan = $B.Dom.attr(td, "rowspan");
                    if (rspan) {
                        rspan = parseInt(rspan) - 1;
                        let tmp = ridx + rspan;
                        if (tmp >= currentRowIndex) {
                            notCreateTd[tdIdx] = true;
                            let colspan = $B.Dom.attr(td, "colspan");
                            if (colspan) {
                                colspan = parseInt(colspan) - 1;
                                while (colspan > 0) {
                                    tdIdx++;
                                    notCreateTd[tdIdx] = true;
                                    colspan--;
                                }
                            }
                            rowspanTds.push(td);
                        }
                    }
                }
            }
            prevRow = prevRow.previousSibling;
        }
        var colNum = parseInt($B.Dom.attr(this.tableEl, "col"));
        var colIdx = 0;
        let cssObj = $B.style2cssObj(this.clickedTd);
        cssObj.height = "auto";
        cssObj.width = "auto";
        while (colIdx < colNum) {
            if (!notCreateTd[colIdx]) {
                newTd = Table.createTD({
                    "tabindex": "0",
                    "row": currentRowIndex,
                    "col": colIdx
                }, cssObj);
                $B.Dom.append(newTr, newTd);
            }
            colIdx++;
        }
        for (let j = 0, len = rowspanTds.length; j < len; ++j) {
            td = rowspanTds[j];
            rspan = parseInt($B.Dom.attr(td, "rowspan")) + 1;
            $B.Dom.attr(td, { "rowspan": rspan });
        }
        this.setWnHFromDom(this.tableEl);
    }
    //打开插入表格对话框
    openInsertTable(onOKfn){       
        let $content = $B.DomUtils.createEl("<p style='padding-top:10px;line-height:50px;'>\u200b</p>");
        let $irow, $icol;
        $B.confirm({
            title: editCfg.label.inputColRow,
            content: $content,
            okFn: () => {//确认回调                   
                let prs = {
                    row: $irow.value,
                    col: $icol.value
                };
                setTimeout(() => {
                    onOKfn(prs);
                }, 10);
            },
            onClosed: () => {
                $B.DomUtils.remove($irow);
                $B.DomUtils.remove($icol);
                $irow = undefined;
                $icol = undefined;
            }
        });
        let $inputWap = $B.DomUtils.createEl(editCfg.inputColRowForm);
        $B.createTextIfr($content, $inputWap, undefined, { height: "50px" });
        if (!this.insertTableEvs) {
            this.insertTableEvs = {
                input: (e) => {
                    console.log(e.target.value);
                }
            };
        }
        $irow = $B.DomUtils.findbyId($inputWap, "row_input");
        $icol = $B.DomUtils.findbyId($inputWap, "col_input");
        $B.DomUtils.input($irow, this.insertTableEvs.input);
        $B.DomUtils.input($icol, this.insertTableEvs.input);
    }
    insertTable() {
        this.hidePanel();
        this.openInsertTable((prs)=>{
            if (this.isEmptyTd(this.clickedTd)) {
                this.removeContent(true);
                this.clearSelected();
                this.editIns.insertTableFn(prs);
            } else {
                $B.message({
                    mask: false,
                    content: '<span style="color:#9D1CF2">' + editCfg.label.insertTableMsg + '</span>',
                    timeout: 2,
                    position: 'top'
                });
            }
        });
        
    }
    removeRow() {
        this.hidePanel();
        var deleteRow = {};
        var hasLoop = this.foreachSeletedTds((td) => {
            let r = parseInt($B.Dom.attr(td, "row"));
            let row = td.parentNode;
            deleteRow[r] = row;
            let rspan = $B.Dom.attr(td, "rowspan");
            if (rspan) {
                let curRow = row;
                rspan = parseInt(rspan) - 1;
                while (rspan > 0) {
                    r++;
                    deleteRow[r] = curRow.nextSibling;
                    curRow = deleteRow[r];
                    rspan--;
                }
            }
        });
        this.makeUndoRec(this.tableEl);
        let rowNum = parseInt($B.Dom.attr(this.tableEl, "row"));
        if (hasLoop) {
            let delKeys = Object.keys(deleteRow);
            if (delKeys.length === rowNum) {
                this.removeTable();
                return;
            } else {
                delKeys.forEach((key) => {
                    this._removeRow(deleteRow[key]);
                });
            }
        } else {
            if (rowNum === 1) {
                this.removeTable();
                return;
            } else {
                this._removeRow(this.clickedTd.parentNode);
            }
        }
        clearTimeout(this._tempTimer);
        this._tempTimer = setTimeout(() => {
            if (!this.fit2parent(this.tableEl)) {
                this.setWnHFromDom(this.tableEl);
            }
        }, 10);
    }
    _removeRow(row) {
        var curRowIndex = parseInt($B.Dom.attr(row, "id").replace("row_", ""));
        var prevRow = row.previousSibling;
        var removeHeight = $B.Dom.height(row);
        var rowSpanTdArray = [];
        var childs, i, len, td, h;
        while (prevRow) {
            childs = prevRow.children;
            for (i = 0, len = childs.length; i < len; ++i) {
                td = childs[i];
                let rowspan = $B.Dom.attr(td, "rowspan");
                let rowIdx = parseInt($B.Dom.attr(td, "row"));
                if (rowspan) {
                    let rIdx = parseInt(rowspan) - 1 + rowIdx;
                    if (rIdx >= curRowIndex) {
                        rowSpanTdArray.push(td);
                    }
                }
            }
            prevRow = prevRow.previousSibling;
        }
        var newTdRec = [];
        childs = row.children;
        for (i = 0, len = childs.length; i < len; ++i) {
            td = childs[i];
            let rowspan = $B.Dom.attr(td, "rowspan");
            if (rowspan) {
                let style = $B.style2cssObj(td); // $B.Dom.attr(td, "style"); 
                style.height = parseFloat($B.Dom.attr(td, "h")) - removeHeight + "px";
                newTdRec.push({
                    style: style,
                    content: td.innerHTML,
                    col: parseInt($B.Dom.attr(td, "col")),
                    rowspan: parseInt(rowspan) - 1,
                    colspan: $B.Dom.attr(td, "colspan")
                });
            }
        }

        var nextRow = row.nextSibling;
        $B.Dom.remove(row);
        for (i = 0, len = rowSpanTdArray.length; i < len; ++i) {
            td = rowSpanTdArray[i];
            h = parseInt($B.Dom.attr(td, "h")) - removeHeight;
            let rs = parseInt($B.Dom.attr(td, "rowspan")) - 1;
            if (rs > 1) {
                $B.Dom.attr(td, { "rowspan": rs });
            } else {
                $B.Dom.removeAttr(td, "rowspan");
                //td.removeAttr("rowspan");
            }
            td.style.height = h + "px";
            td.firstChild.style.height = (h - 1) + "px";
        }
        len = newTdRec.length;
        for (i = 0; i < len; ++i) {
            let rec = newTdRec[i];
            td = Table.createTD({
                "tabindex": "0",
                "row": 0,
                "col": rec.col
            }, rec.style);
            td.innerHTML = rec.content;
            if (rec.rowspan > 1) {
                $B.Dom.attr(td, { "rowspan": rec.rowspan });
            }
            if (rec.colspan) {
                $B.Dom.attr(td, { "colspan": rec.colspan });
            }
            let idx = rec.col;
            if (idx === 0) {
                //td.prependTo(nextRow);
                $B.Dom.prepend(nextRow, td);
            } else {
                idx = idx - 1;
                let childrens = nextRow.children;
                for (let k = 0, klen = childrens.length; k < klen; ++k) {
                    let targetTd = childrens[k];
                    let _index = parseInt($B.Dom.attr(targetTd, "col"));
                    if (idx === _index) {
                        //td.insertAfter(targetTd);
                        $B.Dom.after(targetTd, td);
                        break;
                    } else if (_index > idx) {
                        let prevTd = targetTd.previousSibling;
                        if (prevTd) {
                            $B.Dom.after(prevTd, td);
                            break;
                        } else {
                            //td.insertBefore(targetTd);
                            $B.Dom.before(targetTd, td);
                            break;
                        }
                    } else {
                        let nextTd = targetTd.nextSibling;
                        if (nextTd) {
                            $B.Dom.after(targetTd, td);
                            //td.insertAfter(targetTd);
                        }
                    }
                }
            }
        }
        let rowNum = parseInt($B.Dom.attr(this.tableEl, "row")) - 1;
        $B.Dom.attr(this.tableEl, { "row": rowNum });
        this.fixRowIndex();

    }
    fixRowIndex() {
        console.log("fixRowIndex >>>>>>>>");
        let childs = this.tableEl.firstChild.children;
        for (let i = 0; i < childs.length; i++) {
            let row = childs[i];
            $B.Dom.attr(row, { row: i, id: "row_" + i });
            let tdArr = row.children;
            for (let j = 0; j < tdArr.length; j++) {
                let td = tdArr[j];
                $B.Dom.attr(td, { row: i });
            }
        }
    }
    removeCol() {
        //console.log("removeCol ......");
        this.hidePanel();
        this.makeUndoRec(this.tableEl);
        var colNum = parseInt($B.Dom.attr(this.tableEl, "col"));
        var deleteColMap = {};
        var deleteColArray = [];
        var hasLoop = this.foreachSeletedTds((td) => {
            let col = parseInt($B.Dom.attr(td, "col"));
            if (!deleteColMap[col]) {
                deleteColMap[col] = true;
                deleteColArray.push(col);
                let colspan = $B.Dom.attr(td, "colspan");
                if (colspan) {
                    colspan = parseInt(colspan) - 1;
                    while (colspan > 0) {
                        col++;
                        if (!deleteColMap[col]) {
                            deleteColMap[col] = true;
                            deleteColArray.push(col);
                        }
                        colspan--;
                    }
                }
            }
        });
        if (hasLoop) {
            if (deleteColArray.length === colNum) {
                this.removeTable();
                return;
            } else {
                for (let i = 0, len = deleteColArray.length; i < len; ++i) {
                    let rmTd = deleteColArray[i];
                    this._removeCol(rmTd);
                }
            }
        } else {
            if (colNum === 1) {
                this.removeTable();
                return;
            } else {
                let col = parseInt($B.Dom.attr(this.clickedTd, "col"));
                this._removeCol(col);
            }
        }
        $B.Dom.attr(this.tableEl, { "col": colNum - 1 });
        clearTimeout(this.tableEl);
        this._tempTimer = setTimeout(() => {
            if (!this.fit2parent(this.tableEl)) {
                this.setWnHFromDom(this.tableEl);
            }
        }, 10);
    }
    _removeCol(colIdx) {
        var resetIndexTds = [];
        var trs = this.tableEl.firstChild.children;
        for (let i = 0; i < trs.length; i++) {
            let tr = trs[i];
            let childs = tr.children;
            for (let j = 0; j < childs.length; j++) {
                let td = childs[j];
                let idx = parseInt($B.Dom.attr(td, "col"));
                let endIdx = idx;
                let colspan = $B.Dom.attr(td, "colspan");
                if (colspan) {
                    colspan = parseInt(colspan);
                    let newSpan;
                    endIdx = idx + colspan - 1;
                    if (idx === colIdx) {
                        newSpan = colspan - 1;
                    } else if (endIdx === colIdx) {
                        newSpan = colspan - 1;
                    } else if (idx < colIdx && colIdx < endIdx) {
                        newSpan = colspan - 1;
                    }
                    if (newSpan) {
                        td.firstChild.style.width = "auto";
                        td.style.width = "auto";
                        if (newSpan <= 1) {
                            $B.Dom.removeAttr(td, "colspan");
                            resetIndexTds.push(td.nextSibling);
                            break;
                        } else {
                            $B.Dom.attr(td, { "colspan": newSpan });
                            resetIndexTds.push(td.nextSibling);
                            break;
                        }
                    }
                } else {
                    if (idx === colIdx) {
                        resetIndexTds.push(td.nextSibling);
                        $B.Dom.remove(td);
                        break;
                    } else if (endIdx >= colIdx) {
                        resetIndexTds.push(td);
                        break;
                    }
                }
            }
        }
        for (let i = 0, len = resetIndexTds.length; i < len; ++i) {
            this._reduceNextTdCol(resetIndexTds[i]);
        }
    }
    _reduceNextTdCol(nextTd) {
        while (nextTd) {
            let index = parseInt($B.Dom.attr(nextTd, "col")) - 1;
            $B.Dom.attr(nextTd, { col: index });
            nextTd = nextTd.nextSibling;
        }
    }
    removeContent(notHide) {
        this.makeUndoRec(this.tableEl);
        if (notHide) {
            if (this.clickedTd) {
                let $wap = this.clickedTd.firstChild.firstChild;
                let firstp = $wap.firstChild;
                UTILS.removeAfterEls(firstp);
                firstp.firstChild.innerText = "\u200b";
                UTILS.removeAfterEls(firstp.firstChild);
                this.editIns.move2start(firstp);
            }
        } else {
            this.hidePanel();
            if (this.isSelectedTds()) {
                for (let i = 0; i < this.selectedTdArray.length; i++) {
                    let td = this.selectedTdArray[i];
                    let $wap = td.firstChild.firstChild;
                    let firstp = $wap.firstChild;
                    UTILS.removeAfterEls(firstp);
                    firstp.firstChild.innerText = "\u200b";
                    UTILS.removeAfterEls(firstp.firstChild);
                    if (i === 0) {
                        this.editIns.move2start(firstp);
                    }
                }
            } else {
                if (this.clickedTd) {
                    let $wap = this.clickedTd.firstChild.firstChild;
                    let firstp = $wap.firstChild;
                    UTILS.removeAfterEls(firstp);
                    firstp.firstChild.innerText = "\u200b";
                    UTILS.removeAfterEls(firstp.firstChild);
                    this.editIns.move2start(firstp);
                }
            }
        }
    }
    removeTable() {
        let tableEl = this.tableEl;
        if (tableEl) {
            this.makeUndoRec(tableEl);
            let $prt = tableEl.parentNode;
            $B.DomUtils.remove(tableEl);
            let $span = UTILS.createSpanEl();
            let cssObj = $B.style2cssObj($prt);
            delete cssObj.height;
            delete cssObj.overflow;
            let style = $B.cssObj2string(cssObj);
            $B.DomUtils.attr($prt, { style: style });
            $B.DomUtils.append($prt, $span);
            this.editIns.move2end($span);
            if ($B.DomUtils.hasClass($prt.parentNode.parentNode, "k_edit_td_wap")) {
                $prt.parentNode.parentNode.style.padding = "2px 2px";
                $prt.parentNode.style.width = "auto";
                $prt.parentNode.style.height = "auto";
            }
            this.onRemoved();
            this.hidePanel();
        }
    }
    /**
     * 轮询选择的td，如果不选择则为当前点击td
     * **/
    foreachCssTd(fn) {
        if (!this.foreachSeletedTds(fn)) {
            fn(this.clickedTd);
        }
    }
    foreachTdInnerPls(fn, isOnlyPel) {
        this.foreachCssTd((td) => {
            this.loopCssElInTd(td, ($p, $s) => {
                fn($p, $s, td);
            });
        }, isOnlyPel);
    }
    loopCssElInTd(td, fn, isOnlyPel) {
        let plist = td.firstChild.firstChild.children;
        for (let i = 0; i < plist.length; i++) {
            let pel = plist[i];
            if (pel.firstChild.nodeName === "TABLE") {
                this.foreachTd(pel.firstChild, (td) => {
                    this.loopCssElInTd(td, fn, isOnlyPel);
                });
            } else {
                if (isOnlyPel) {
                    fn(pel);
                } else {
                    let childs = pel.children;
                    for (let j = 0; j < childs.length; j++) {
                        fn(pel, childs[j]);
                    }
                }
            }
        }
    }
    boldFn(params, $evEl) {
        let css = UTILS.getBoldCss($evEl);
        this.foreachCssTd((td) => {
            this.loopCssElInTd(td, (pel, el) => {
                el.style.fontWeight = css;
            });
        });
    }
    italicFn(params, $evEl) {
        let css = UTILS.getitalicCss($evEl);
        this.foreachCssTd((td) => {
            this.loopCssElInTd(td, (pel, el) => {
                el.style.fontStyle = css;
            });
        });
    }
    fontColorFn(params, $evEl) {
        this.editIns.changeSelectionColor("color", params.color);
        this.foreachCssTd((td) => {
            this.loopCssElInTd(td, (pel, el) => {
                el.style.color = params.color;
            });
        });
    }
    backgroundColorFn(params, $evEl) {
        this.editIns.changeSelectionColor("background-color", params.color);
        this.foreachCssTd((td) => {
            td.style.backgroundColor = params.color;
            this.loopCssElInTd(td, (pel, el) => {
                el.style.backgroundColor = params.color;
            });
        });
    }
    fontSizeFn(params, $evEl) {
        let pMap = {};
        let tdMap = {};
        this.foreachTdInnerPls(($p, $s, $td) => {
            if (!pMap[$p.id]) {
                let data = UTILS.getLineHightData($p);
                pMap[$p.id] = { el: $p, data: data };
            }
            $s.style.fontSize = params;
            let row = $B.Dom.attr($td, "row");
            if (!tdMap[row]) {
                tdMap[row] = $td;
            }
        });
        //更新行高      
        let keys = Object.keys(pMap);
        for (let i = 0; i < keys.length; i++) {
            let $p = pMap[keys[i]].el;
            let data = pMap[keys[i]].data;
            let maxFont = UTILS.getMaxFontSize($p);
            let newHeight = maxFont * data.r + "px";
            $B.DomUtils.css($p, { "line-height": newHeight });
        }
        for (let p in tdMap) {
            this.tdfit2content(tdMap[p]);
        }
    }
    fontFamilyFn(params, $evEl) {
        this.foreachCssTd((td) => {
            this.loopCssElInTd(td, (pel, el) => {
                el.style.fontFamily = params;
                pel.style.fontFamily = params;
            });
        });
    }
    underlineFn(params, $evEl) {
        let css = "underline";
        this.textDecoration(css, $evEl);
    }
    strikethroughFn(params, $evEl) {
        let css = "line-through";
        this.textDecoration(css, $evEl);
    }
    textDecoration(css, $evEl) {
        if (UTILS.isHightLight($evEl)) {
            css = "none";
            UTILS.removeHightLight($evEl);
        } else {
            UTILS.addHightLight($evEl);
            if (css === "underline") {
                UTILS.removeHightLight($evEl.nextSibling);
            } else {
                UTILS.removeHightLight($evEl.previousSibling);
            }
        }
        this.foreachCssTd((td) => {
            this.loopCssElInTd(td, (pel, el) => {
                el.style.textDecoration = css;
            });
        });
    }
    superscriptFn(css, $evEl) {
        this.textVertical("super", $evEl);
    }
    subscriptFn(css, $evEl) {
        this.textVertical("sub", $evEl);
    }
    textVertical(css, $evEl) {
        let set = true;
        if (UTILS.isHightLight($evEl)) {
            UTILS.removeHightLight($evEl);
            set = false;
        } else {
            UTILS.addHightLight($evEl);
            if (css === "super") {
                UTILS.removeHightLight($evEl.nextSibling);
            } else {
                UTILS.removeHightLight($evEl.previousSibling);
            }
        }
        this.foreachCssTd((td) => {
            this.loopCssElInTd(td, (pel, el) => {
                if (set) {
                    el.style.verticalAlign = css;
                } else {
                    let obj = $B.style2cssObj(el);
                    delete obj["vertical-align"];
                    let attr = $B.cssObj2string(obj);
                    $B.DomUtils.attribute(el, { "style": attr });
                }
            });
        });
    }
    fontTitleFn(params, $evEl) {
        let tdMap = {};
        this.foreachCssTd((td) => {
            let r = $B.Dom.attr(td, "row");
            if (!tdMap[r]) {
                tdMap[r] = td;
            }
            this.loopCssElInTd(td, (pel, $s) => {
                $s.style.fontSize = params;
                if (params === editCfg.textFontSize) {
                    $s.style.fontWeight = "normal";
                } else {
                    $s.style.fontWeight = "bold";
                }
            });
        });
        for (let p in tdMap) {
            this.tdfit2content(tdMap[p]);
        }
    }
    fontSpaceFn(params, $evEl) {
        this.foreachCssTd((td) => {
            let pIdMap = {};
            this.loopCssElInTd(td, (pel, el) => {
                if (params.forp) {
                    let id = pel.id;
                    if (!pIdMap[id]) {
                        pIdMap[id] = 1;
                        pel.style.letterSpacing = params["letter-spacing"];
                    }
                }
                el.style.letterSpacing = params["letter-spacing"];
            });
        });
    }
    pindentFn(params, $evEl) {
        this.forPels(($p) => {
            let indent = params.indent;
            UTILS.indentPFn(indent, $p);
        });
    }
    plineHeight(params, $text) {
        let v;
        if (params["line-height"]) {
            v = params["line-height"] + "px";
        }
        let tds = {};
        this.forPels(($p) => {
            if (typeof v !== "undefined") {
                $p.style.lineHeight = v;
            } else if (params.lineR) {
                let s = UTILS.getMaxFontSize($p) * params.lineR;
                $p.style.lineHeight = s + "px";
                $text.value = s;
            }
            let td = $p.parentNode.parentNode;
            let r = $B.Dom.attr(td, "row");
            let h = this.getTdContentHeight(td);
            if (tds[r]) {
                if (tds[r].h > h) {
                    tds[r] = { el: td, h: h };
                }
            } else {
                tds[r] = { el: td, h: h };
            }
        });
        let keys = Object.keys(tds);
        for (let i = 0; i < keys.length; i++) {
            this.tdfit2content(tds[keys[i]].el);
        }
    }
    pborderFn(params, $evEl) {
        this.forPels(($p) => {
            UTILS.setBorderCss($p, params);
        });
    }
    ppadding(params, $evEl) {
        console.log("ppading ", params);
        let go = true;
        if (this.editIns.isSelected()) {
            //如果存在单元格划选的段落
            if (this.cssPelist.length > 0) {
                for (let i = 0; i < this.cssPelist.length; i++) {
                    $B.DomUtils.css(this.cssPelist[i], params);
                }
                this.tdfit2content(this.clickedTd);
                return false;
            } else {
                go = false;
            }
        }
        if (go) {//修饰td
            let tds = {};
            let go = this.foreachSeletedTds((td) => {
                this.padding2td(td, params);
                let r = $B.Dom.attr(td, "row");
                let h = this.getTdContentHeight(td);
                if (tds[r]) {
                    if (tds[r].h > h) {
                        tds[r] = { el: td, h: h };
                    }
                } else {
                    tds[r] = { el: td, h: h };
                }
            });
            if (go) {
                let keys = Object.keys(tds);
                for (let i = 0; i < keys.length; i++) {
                    this.tdfit2content(tds[keys[i]].el);
                }
            } else {
                this.padding2td(this.clickedTd, params);
                this.tdfit2content(this.clickedTd);
            }
        } else {
            return true;
        }

    }
    padding2td(td, css) {
        let key = Object.keys(css)[0];
        let $wap = td.firstChild.firstChild;
        let childs = $wap.children;
        if (key.indexOf("-top") > 0) {
            childs[0].style.paddingTop = css["padding-top"];
        } else if (key.indexOf("-right") > 0) {
            for (let i = 0; i < childs.length; i++) {
                childs[i].style.paddingRight = css["padding-right"];
            }
        } else if (key.indexOf("-bottom") > 0) {
            $wap.lastChild.style.paddingBottom = css["padding-bottom"];
        } else if (key.indexOf("-left") > 0) {
            for (let i = 0; i < childs.length; i++) {
                childs[i].style.paddingLeft = css["padding-left"];
            }
        }
    }
    getTdContentHeight(td) {
        let childs = td.firstChild.firstChild.children;
        let h = 0;
        for (let i = 0; i < childs.length; i++) {
            h = h + $B.Dom.height(childs[i]) + 2;
        }
        return h;
    }
    /**
     * td高度根据内容自动适配
     * ***/
    tdfit2content(td) {
        //console.log("tdfit2content tdfit2content");
        let trH = $B.Dom.height(td.parentNode);
        let h = this.getTdContentHeight(td);
        if (h > trH) {
            let diff = h - trH + 2;
            this.updateRowHeightByDiff(td.parentNode, diff, undefined, undefined);
        }
        //let ch = $B.Dom.height();
    }
    /**
     * 段落字体颜色
     * **/
    pcolorFn(params, $evEl) {
        this.forPels(($p) => {
            this.editIns.loopPelSapn($p, ($s) => {
                $s.style.color = params.color;
            });
        });
        this.editIns.changeSelectionColor("color", params.color);
    }
    /**
     * 段落背景色
     * ***/
    pbackground(params, $evEl) {
        this.forPels(($p) => {
            this.editIns.loopPelSapn($p, ($s) => {
                $s.style.backgroundColor = params.color;
            });
            $p.style.backgroundColor = params.color;
        });
        this.editIns.changeSelectionColor("background-color", params.color);
    }
    alignLeftFn(params, $evEl) {
        this.hAlignFn("left");
        if ($evEl) {
            $B.Dom.addClass($evEl, "k_edit_tools_hlight");
            $B.Dom.removeClass($evEl.nextSibling, "k_edit_tools_hlight");
            $B.Dom.removeClass($evEl.nextSibling.nextSibling, "k_edit_tools_hlight");
        }
    }
    alignCenterFn(params, $evEl) {
        this.hAlignFn("center");
        if ($evEl) {
            $B.Dom.addClass($evEl, "k_edit_tools_hlight");
            $B.Dom.removeClass($evEl.previousSibling, "k_edit_tools_hlight");
            $B.Dom.removeClass($evEl.nextSibling, "k_edit_tools_hlight");
        }
    }
    alignRightFn(params, $evEl) {
        this.hAlignFn("right");
        if ($evEl) {
            $B.Dom.addClass($evEl, "k_edit_tools_hlight");
            $B.Dom.removeClass($evEl.previousSibling, "k_edit_tools_hlight");
            $B.Dom.removeClass($evEl.previousSibling.previousSibling, "k_edit_tools_hlight");
        }
    }
    hAlignFn(css) {
        this.foreachTdInnerPls(($p) => {
            $p.style["textAlign"] = css;
        }, true);
    }
    vAlignTop() {
        console.log("vAlignTop ");
        this.foreachCssTd((td) => {
            td.style["verticalAlign"] = "top";
            let el = td.firstChild;
            let styleObj = $B.style2cssObj(el);
            delete styleObj.display;
            delete styleObj["align-items"];
            let style = $B.cssObj2string(styleObj);
            $B.Dom.attr(el, { style: style });
            this.alterPlistAlign(el, "auto");
        });
    }
    vAlignMiddel() {
        this.foreachCssTd((td) => {
            td.style["verticalAlign"] = "middle";
            let el = td.firstChild;
            el.style.display = "flex";
            el.style["alignItems"] = "center";
            this.alterPlistAlign(el, "100%");
        });
        console.log("vAlignMiddel ");
    }
    vAlignBottom() {
        console.log("vAlignBottom ");
        this.foreachCssTd((td) => {
            td.style["verticalAlign"] = "bottom";
            let el = td.firstChild;
            el.style.display = "flex";
            el.style["alignItems"] = "flex-end";
            this.alterPlistAlign(el, "100%");
        });
    }    
    alterPlistAlign(el, val) {
        let childs = el.children;
        for (let i = 0; i < childs.length; i++) {
            childs[i].style.width = val;
        }
    }
    static createTR(attr, css) {
        var tr = $B.DomUtils.createEl("<tr></tr>");
        if (attr) {
            $B.DomUtils.attribute(tr, attr);
        }
        if (css) {
            $B.DomUtils.css(tr, css);
        }
        return tr;
    }
    static createTD(attr, css) {
        var $p = UTILS.createPEl();
        var td = $B.DomUtils.createEl("<td contenteditable='false' id='" + $B.generateDateUUID() + "' style='vertical-align:top;box-sizing: border-box;'><div class='k_edit_td_wap' style='padding:2px 2px;width:100%;height:100%;overflow:hidden;box-sizing: border-box;'><div contenteditable='true' class='k_td_inner_wap' style='width:auto;height:auto;'></div></div></td>");
        $B.DomUtils.append(td.firstChild.firstChild, $p);
        if (attr) {
            $B.DomUtils.attribute(td, attr);
           // $p.firstChild.innerText = attr.row + "_" + attr.col;
        }
        if (css) {
            $B.DomUtils.css(td, css);
            if (css.height && css.height.indexOf("px") > 0) {
                let innerHeight = parseFloat(css.height.replace("px", "")) - 1;
                td.firstChild.style.height = innerHeight + "px";
            }
        }
        return td;
    }
    static getTable(row, col) {
        let $tab = $B.DomUtils.createEl("<table class='k_edit_table_cls' id='" + $B.generateDateUUID() + "' row='" + row + "' col='" + col + "' style='border-collapse:collapse;width:100%;height:auto;table-layout:fixed;box-sizing: border-box;'><tbody></tbody></table>");
        return $tab;
    }
}
Keditor.extend({
    testFn: function () {
        console.log("api testFn", this);
    },
    saveFn: function () {
        let html = this.$input.innerHTML;
        console.log(html);       
    },
    paintBrushFn: function (params, $evEl) {        
        let r = this._getDomRange();
        this.$brushBtn = $evEl;
        if (r && !r.collapsed) {
            let ret = this.getSpanAndPCss();
            let spanCss = ret.spanCss;
            $B.confirm({
                okIcon: "fa-ok-circled",
                noIcon: "fa-cancel-circled",
                title: editCfg.label.brushTitle,
                content: editCfg.label.brushConfirm,
                okText: editCfg.label.yesTitle,
                noText: editCfg.label.noTitle,
                okFn: () => {
                    this.BrushingCSS = ret;    
                    let $p = this.getFocusEle(true);
                    let listObj = this.anyliscList($p);
                    if(listObj){
                        this.BrushingCSS.listObj = listObj;
                        this.BrushingCSS.srcp = $p;
                    }
                },
                noFn: () => {
                    this.BrushingCSS = { spanCss: spanCss };  
                    let $p = this.getFocusEle(true);
                    let listObj = this.anyliscList($p);
                    if(listObj){
                        this.BrushingCSS.listObj = listObj;
                        this.BrushingCSS.srcp = $p;
                    }                  
                },
                onClosed:()=>{                    
                    if(!this.BrushingCSS){
                        $B.Dom.removeClass(this.$brushBtn.firstChild, "k_edit_brush_actived");
                    }
                }
            });
            $B.Dom.addClass(this.$brushBtn.firstChild, "k_edit_brush_actived");
        } else {
            $B.alert(editCfg.label.availableBrush, 1.5);
        }
    },
    exeBrushing2el: function (params) {
        setTimeout(()=>{     
            this.makeUndoData();
            this.putUndoData();      
            let spanCss = params.spanCss;
            let pCss = params.pCss;
            this.getCssEls();           
            UTILS.fontWeightConver(spanCss);
            for(let i =0 ; i < this.cssEls.length ;i++){
                $B.Dom.css(this.cssEls[i],spanCss);
            }
            if(pCss){               
                let css = {
                    "border-bottom": pCss["border-bottom"],
                    "border-left":  pCss["border-left"],
                    "border-right":  pCss["border-right"],
                    "border-top":  pCss["border-top"],
                    "padding-bottom":  pCss["padding-bottom"],
                    "padding-left":  pCss["padding-left"],
                    "padding-right":  pCss["padding-right"],
                    "padding-top":  pCss["padding-top"],
                    "backgorund-color":  pCss["backgorund-color"],
                    "text-align":  pCss["text-align"]
                };
                for(let i =0 ; i < this.cssPEls.length ;i++){
                    $B.Dom.css(this.cssPEls[i],css);
                }
            }
            //是否是序列格式
            if(params.listObj){
                let $p = this.cssPEls[0];
                if($p !== params.srcp){
                    params.listObj.usePrs = true;
                    this.updateListSeq($p,params.listObj);
                }
                params.srcp = undefined;
                params.listObj = undefined;
            }
            setTimeout(()=>{
                this.reactiveTools();
            },1);
        },100);
    },
    clearFn: function () {
        $B.confirm(editCfg.label.clearConfirm, () => {
            this._clearFn();
        }, () => {
            this.rebuildRegion();
        }, () => {
            this.rebuildRegion();
        });
    },
    _clearFn:function(){
        this.makeUndoData("clearFn");//插入撤销重做
        this.putUndoData(1);
        let $p = this.$input.firstChild;
        let $n = $p.nextSibling;
        while ($n) {
            let $0 = $n.nextSibling;
            this.$input.removeChild($n);
            $n = $0;
        }
        $B.Dom.removeChilds($p);
        let $1 = UTILS.createSpanEl();
        $B.Dom.append($p,$1);         
        setTimeout(() => {
            this.move2end($1);
            setTimeout(() => {
                this.reactiveTools();
            }, 1);
        }, 1);
    },
    eraserFn: function () {
        this.activedLinePELS();
        let $w = $B.window({
            iconCls: "fa-help-1",
            expandable: false, //可左右收缩
            maxminable: false, //可变化小大
            collapseable: false, //上下收缩
            resizeable: false,
            width: 400,
            title: editCfg.label.clearTitle,
            onClosed: () => {
                this.unactivedLinePELS();
            },
            content: '<div><p style="line-height:28px;text-align:center;font-size:16px;">' + editCfg.label.clearTitle2 + '</p></div>',
            toolbar: {
                align: '100%',
                buttons: [
                    {
                        color: '#E8E8F5',
                        text: editCfg.label.clearSelect,
                        iconCls: 'fa-brush',
                        click: () => {
                            $w.close();
                            if (this.cssEls.length === 0) {
                                this.getCssEls();
                            }
                            if (this.cssEls.length > 0) {
                                for (let i = 0; i < this.cssEls.length; i++) {
                                    let $s = this.cssEls[i];
                                    $B.Dom.attr($s, { style: editCfg.spanCss });
                                }
                                setTimeout(() => {
                                    this.reactiveTools();
                                }, 1);
                            }
                        }
                    },
                    {
                        color: '#F2F2FC',
                        text: editCfg.label.clearPlist,
                        iconCls: 'fa-list-bullet',
                        click: () => {
                            $w.close();
                            if (this.cssEls.length === 0) {
                                this.getCssEls();
                            }
                            if (this.cssPEls.length > 0) {
                                for (let i = 0; i < this.cssPEls.length; i++) {
                                    let $p = this.cssPEls[i];
                                    $B.Dom.attr($p, { style: editCfg.pElementCss });
                                    if ($p.firstChild.nodeName === "TABLE") {
                                        this.tableIns.resetCss($p.firstChild);
                                    } else {
                                        let childs = $p.children;
                                        for (let j = 0; j < childs.length; j++) {
                                            let $s = childs[j];
                                            $B.Dom.attr($s, { style: editCfg.spanCss });
                                        }
                                    }
                                }
                                setTimeout(() => {
                                    this.reactiveTools();
                                }, 1);
                            }
                        }
                    }, {
                        color: '#E8E8F5',
                        text: editCfg.label.clearAll,
                        iconCls: 'fa-cancel',
                        click: () => {
                            $w.close();
                            let children = this.$input.children;
                            for (let i = 0; i < children.length; i++) {
                                let $p = children[i];
                                if ($B.Dom.hasClass($p, "p_element")) {
                                    $B.Dom.attr($p, { style: editCfg.pElementCss });
                                    if ($p.firstChild.nodeName === "TABLE") {
                                        this.tableIns.resetCss($p.firstChild);
                                    } else {
                                        let childs = $p.children;
                                        for (let j = 0; j < childs.length; j++) {
                                            let $s = childs[j];
                                            $B.Dom.attr($s, { style: editCfg.spanCss });
                                        }
                                    }
                                }
                            }
                            setTimeout(() => {
                                this.reactiveTools();
                            }, 1);
                        }
                    }
                ]
            }
        });
    },
    boldFn: function (params, $evEl) {
        let css = UTILS.getBoldCss($evEl);
        this.loopSpanCssEls((el) => {
            el.style.fontWeight = css;
        });
    },
    italicFn: function (params, $evEl) {
        let css = UTILS.getitalicCss($evEl);
        this.loopSpanCssEls((el) => {
            el.style.fontStyle = css;
        });
    },
    fontColorFn: function (params, $evEl) {
        this.loopSpanCssEls((el) => {
            el.style.color = params.color;
        });
        this.changeSelectionColor("color", params.color);
    },
    backgroundColorFn: function (params, $evEl) {
        this.loopSpanCssEls((el) => {
            el.style.backgroundColor = params.color;
            el.style.opacity = params.opacity;
        });
        this.changeSelectionColor("background-color", params.color);
    },
    fontSizeFn: function (params, $evEl) {
        let map = {};
        this.loopPelCssEls(($p, i) => {
            map[i] = UTILS.getLineHightData($p);
        });
        let v = parseFloat(params.replace("px", ""));
        this.loopSpanCssEls((el) => {
            el.style.fontSize = params;
        });
        //需要更新行高
        this.loopPelCssEls(($p, i) => {
            let maxFont = UTILS.getMaxFontSize($p);
            let newHeight = maxFont * map[i].r + "px";
            $B.DomUtils.css($p, { "line-height": newHeight });
        });
    },
    fontFamilyFn: function (params, $evEl) {
        //console.log("family",params);
        this.loopSpanCssEls((el) => {
            el.style.fontFamily = params;
        });
    },
    underlineFn: function (params, $evEl) {
        let css = "underline";
        this.textDecoration(css, $evEl);
    },
    strikethroughFn: function (params, $evEl) {
        let css = "line-through";
        this.textDecoration(css, $evEl);
    },
    textDecoration: function (css, $evEl) {
        if (UTILS.isHightLight($evEl)) {
            css = "none";
            UTILS.removeHightLight($evEl);
        } else {
            UTILS.addHightLight($evEl);
            if (css === "underline") {
                UTILS.removeHightLight($evEl.nextSibling);
            } else {
                UTILS.removeHightLight($evEl.previousSibling);
            }
        }
        this.loopSpanCssEls((el) => {
            el.style.textDecoration = css;
        });
    },
    superscriptFn: function (css, $evEl) {
        this.textVertical("super", $evEl);
    },
    subscriptFn: function (css, $evEl) {
        this.textVertical("sub", $evEl);
    },
    textVertical: function (css, $evEl) {
        let set = true;
        if (UTILS.isHightLight($evEl)) {
            UTILS.removeHightLight($evEl);
            set = false;
        } else {
            UTILS.addHightLight($evEl);
            if (css === "super") {
                UTILS.removeHightLight($evEl.nextSibling);
            } else {
                UTILS.removeHightLight($evEl.previousSibling);
            }
        }
        this.loopSpanCssEls((el) => {
            if (set) {
                el.style.verticalAlign = css;
            } else {
                let obj = $B.style2cssObj(el);
                delete obj["vertical-align"];
                let attr = $B.cssObj2string(obj);
                $B.DomUtils.attribute(el, { "style": attr });
            }
        });
    },
    fontTitleFn: function (params, $evEl) {
        this.loopPelCssEls(($p, i) => {
            this.loopPelSapn($p, ($s) => {
                $s.style.fontSize = params;
                if (params === editCfg.textFontSize) {
                    $s.style.fontWeight = "normal";
                } else {
                    $s.style.fontWeight = "bold";
                }
            });
        });
    },
    fontSpaceFn: function (params, $evEl) {
        //console.log(params,$evEl);
        if (params.forp) {
            this.loopPelCssEls(($p) => {
                this.loopPelSapn($p, ($s) => {
                    $s.style.letterSpacing = params["letter-spacing"];
                });
            });
        } else {
            this.loopSpanCssEls((el) => {
                el.style.letterSpacing = params["letter-spacing"];
            });
        }
    },
    pindentFn: function (params, $evEl) {
        this.loopPelCssEls(($p) => {
            let indent = params.indent;
            UTILS.indentPFn(indent, $p);
            // if(indent !== 0){
            //     let $f = UTILS.getFirstTextEL($p);
            //     let size = parseFloat($B.DomUtils.css($f,"font-size").replace("px",""));
            //     indent = params.indent * size;              
            // }
            // $p.style.textIndent = indent + "px";
        });
    },
    plineHeight: function (params, $text) {
        let v;
        if (params["line-height"]) {
            v = params["line-height"] + "px";
        }
        this.loopPelCssEls(($p) => {
            if (typeof v !== "undefined") {
                $p.style.lineHeight = v;
            } else if (params.lineR) {
                let s = UTILS.getMaxFontSize($p) * params.lineR;
                $p.style.lineHeight = s + "px";
                $text.value = s;
            }
        });
    },
    pborderFn: function (params, $evEl) {
        this.loopPelCssEls(($p) => {
            UTILS.setBorderCss($p, params);
        });
    },
    ppadding: function (params, $evEl) {
        this.loopPelCssEls(($p) => {
            $B.DomUtils.css($p, params);
        });
    },
    /**
     * 段落字体颜色
     * **/
    pcolorFn: function (params, $evEl) {
        this.loopPelCssEls(($p) => {
            this.loopPelSapn($p, ($s) => {
                $s.style.color = params.color;
            });
        });
        this.changeSelectionColor("color", params.color);
    },
    /**
     * 段落背景色
     * ***/
    pbackground: function (params, $evEl) {
        this.loopPelCssEls(($p) => {
            this.loopPelSapn($p, ($s) => {
                $s.style.backgroundColor = params.color;
            });
            $p.style.backgroundColor = params.color;
        });
        this.changeSelectionColor("background-color", params.color);
    },
    insertTableFn: function (params, $evEl) {
        console.log("insertTableFn", params);
        let row = params.row;
        let col = params.col;
        let $tab = Table.getTable(row, col);
        let $body = $tab.firstChild;
        for (let i = 0; i < row; ++i) {
            let tr = Table.createTR({
                "id": "row_" + i
            });
            for (let j = 0; j < col; ++j) {
                let td = Table.createTD({
                    "tabindex": "0",
                    "row": i,
                    "col": j
                });
                $B.DomUtils.append(tr, td);
            }
            $B.DomUtils.append($body, tr);
        }
        let $p = this.getFocusEle(true);
        if ($p) {
            let txt = $p.innerText.replaceAll("\u200b", "");
            if (txt !== "") {
                $p = this.insertNewPAfter($p);                
            }      
            this.move2end($p);
            //插入表格的撤销重做
            this.makePutUndoImd(true);
            let isInTd = false;
            let $prtd = $p.parentNode;//父单元格
            let helper = 0;
            while ($prtd && helper <= 6) {
                if ($prtd.nodeName === "TD") {
                    isInTd = true;
                    break;
                }
                $prtd = $prtd.parentNode;
                helper++;
            }
            $p.innerHTML = "";
            if (isInTd) {
                if (!this.tableIns.isEmptyTd($prtd)) {
                    $B.message({
                        mask: false,
                        content: '<span style="color:#9D1CF2">' + editCfg.label.insertTableMsg + '</span>',
                        timeout: 2,
                        position: 'top'
                    });
                    return;
                }
                let $pre = $p.previousSibling;
                while ($pre) {
                    $B.Dom.remove($pre);
                    $pre = $pre.nextSibling;
                }
                $pre = $p.nextSibling;
                while ($pre) {
                    $B.Dom.remove($pre);
                    $pre = $pre.nextSibling;
                }
                this.tableIns.clear4border($tab);
                let $tdWap = $prtd.firstChild;
                $B.DomUtils.css($tdWap, { "padding": "0px 0px" });
                $B.DomUtils.css($tdWap.firstChild, { width: '100%', height: '100%' });
                $B.DomUtils.css($p, { width: '100%', height: '100%', overflow: 'hidden', "padding": "0px 0px", "margin": "0px 0px" });
                //期待的高度,与当前嵌套单元格的高度比较
                let expHeight = row * 26 + 2;
                let tdHeight = $B.DomUtils.height($prtd);
                if (expHeight > tdHeight) { //高度不足，先撑开行高度
                    let diff = expHeight - tdHeight;
                    this.tableIns.updateRowHeightByDiff($prtd.parentNode, diff)
                }
            }
            $B.DomUtils.append($p, $tab);
            $p.contenteditable = false;
            $B.DomUtils.addClass($p, 'k_edit_p_relative');
            this.tableIns.bindEvents($tab);
            if (!isInTd && !$p.nextSibling) {
                this.insertNewPAfter($p);
            }
            if (isInTd) {
                //更新一次被插入行的高度
                this.tableIns.updateRowWnHFromDom($prtd.parentNode);
                this.tableIns.fit2parent($tab);
            } else {
                this.tableIns.setWnHFromDom($tab);
            }
            let td = $tab.firstChild.firstChild.firstChild;
            this.move2start(td.firstChild.firstChild);
            this.tableIns.setTarget($tab);
            this.tableIns.setClickTd(td);
            this.tableIns.hidePanel();
        }
    },
    alignLeftFn: function (params, $evEl) {
        this.alignFn("left");
        $B.Dom.addClass($evEl, "k_edit_tools_hlight");
        $B.Dom.removeClass($evEl.nextSibling, "k_edit_tools_hlight");
        $B.Dom.removeClass($evEl.nextSibling.nextSibling, "k_edit_tools_hlight");
    },
    alignCenterFn: function (params, $evEl) {
        this.alignFn("center");
        $B.Dom.addClass($evEl, "k_edit_tools_hlight");
        $B.Dom.removeClass($evEl.previousSibling, "k_edit_tools_hlight");
        $B.Dom.removeClass($evEl.nextSibling, "k_edit_tools_hlight");
    },
    alignRightFn: function (params, $evEl) {
        this.alignFn("right");
        $B.Dom.addClass($evEl, "k_edit_tools_hlight");
        $B.Dom.removeClass($evEl.previousSibling, "k_edit_tools_hlight");
        $B.Dom.removeClass($evEl.previousSibling.previousSibling, "k_edit_tools_hlight");
    },
    alignFn: function (css) {
        this.loopPelCssEls(($p) => {
            $p.style["textAlign"] = css;
        });
    },
    linkFn: function (params) {
        console.log("linkFN", params);
        let r = this._getDomRange();
        let href = params.addr;
        if (href.indexOf("http") !== 0) {
            href = "http://" + href;
        }
        let attr = "";
        if (params.isBlank) {
            attr = "target='_blank'";
        }
        let id = $B.generateDateUUID();
        if (r.collapsed) {
            if (r.startContainer.nodeType === 3) {
                let $s1 = r.startContainer.parentNode;
                let ret = this.splitWrapText($s1, r.startOffset, r.endOffset);
                $s1.style.display = "none";
                let targetEL = $s1;
                let linkEL;
                for (let i = 0; i < ret.length; i++) {
                    let el = ret[i];
                    $B.Dom.after(targetEL, el);
                    targetEL = el;
                    if ($B.Dom.hasClass(el, "_region_span")) {
                        $B.Dom.removeClass(el, "_region_span");
                        $B.Dom.addClass(el, "_hyper_link");
                        let style = $B.Dom.attr(el, "style");
                        el.innerHTML = "<a style='" + style + "' id='" + id + "' " + attr + " href='" + href + "'>" + params.name + "</a>";
                        linkEL = el;
                    }
                }
                $B.Dom.remove($s1);
                this.setRegionByEl(linkEL.firstChild, linkEL.firstChild);
                $B.Dom.attr(linkEL, { contenteditable: false });
                if (!linkEL.nextSibling) {
                    $B.Dom.after(linkEL, UTILS.createSpanEl());
                }
            } else {
                $B.alert(editCfg.label.availableInsert, 1.6);
            }
        } else {
            let el = this.cssEls[0];
            if (el.nodeName === "A") {
                el = el.parentNode;
            }
            let style = $B.Dom.attr(el, "style");
            let i = 1;
            let prter = el.parentNode;
            while (i < this.cssEls.length) {
                prter.removeChild(this.cssEls[i]);
                i++;
            }
            $B.Dom.attr(linkEL, { contenteditable: false });
            el.innerHTML = "<a style='" + style + "' id='" + id + "' " + attr + " href='" + href + "'>" + params.name + "</a>";
            this.setRegionByEl(el.firstChild, el.firstChild);
            if (!el.nextSibling) {
                $B.Dom.after(el, UTILS.createSpanEl());
            }
            if (!el.previousSibling) {
                $B.Dom.before(el, UTILS.createSpanEl());
            }
        }
    },
    pictureFn: function (params) {
        if (params.url !== "") {
            let r = this._getDomRange();
            if (r.collapsed && r.startContainer.nodeType === 3) {
                let position = params.pos;
                let padding = {
                    "padding-top": params.top + "px",
                    "padding-right": params.right + "px",
                    "padding-bottom": params.bottom + "px",
                    "padding-left": params.left + "px"
                };
                let $s1 = r.startContainer.parentNode;
                let $img = this.createImage(params);
                $B.Dom.css($img, padding);
                if (position === "center") {//无环绕独占一行
                    let $p = this._getPelByChild($s1);
                    if (!UTILS.isEmptyEl($p)) {
                        let $p1 = UTILS.createPEl();
                        $B.Dom.after($p, $p1);
                        $p = $p1;
                        if (!$p.nextSibling) {
                            $B.Dom.after($p, UTILS.createPEl());
                        }
                    }
                    $B.Dom.append($p.firstChild, $img);
                    $B.Dom.addClass($p.firstChild, "_img_link");
                    if (!$p.firstChild.nextSibling) {
                        let $nextSp = UTILS.createSpanEl();
                        $B.Dom.after($p.firstChild, $nextSp);
                    }
                    $B.Dom.attr($p.firstChild, { "contenteditable": false });
                    setTimeout(() => {
                        this.move2start($p.firstChild.nextSibling);
                    }, 1);
                } else {
                    let ret = this.splitWrapText($s1, r.startOffset, r.endOffset);
                    let imgEL;
                    if(Array.isArray(ret)){
                        $s1.style.display = "none";
                        let targetEL = $s1;                        
                        for (let i = 0; i < ret.length; i++) {
                            let el = ret[i];
                            $B.Dom.after(targetEL, el);
                            targetEL = el;
                            if ($B.Dom.hasClass(el, "_region_span")) {
                                $B.Dom.removeClass(el, "_region_span");
                                $B.Dom.addClass(el, "_img_link");
                                el.innerHTML = "";
                                imgEL = el;
                            }
                        }
                        $B.Dom.remove($s1);
                        $B.Dom.append(imgEL, $img);
                    }else{
                        imgEL = ret;
                        imgEL.innerHTML="";
                        $B.Dom.append(imgEL, $img);
                        $B.Dom.removeClass(imgEL, "_region_span");
                    }                   
                    if (!imgEL.nextSibling) {
                        let $nextSp = UTILS.createSpanEl();
                        $B.Dom.after(imgEL, $nextSp);
                    }
                    if (!imgEL.previousSibling) {
                        let $nextSp = UTILS.createSpanEl();
                        $B.Dom.before(imgEL, $nextSp);
                    }
                    $B.Dom.attr(imgEL, { "contenteditable": false });
                    setTimeout(() => {
                        this.move2start(imgEL.nextSibling);
                    }, 1);
                    if (position === "right") {
                        imgEL.style.float = "right";
                        let prt = imgEL.parentNode;
                        $B.Dom.remove(imgEL);
                        $B.Dom.append(prt, imgEL);
                    } else if (position === "left") {
                        imgEL.style.float = "left";
                        let prt = imgEL.parentNode;
                        $B.Dom.remove(imgEL);
                        $B.Dom.prepend(prt, imgEL);
                    }
                }
            } else {
                $B.alert(editCfg.label.availableInsert, 1.6);
            }
        }
    },
    pictureEditFn: function (params) {
        let css = {
            width: params.width + "px",
            height: params.height + "px",
            "padding-top": params.top + "px",
            "padding-right": params.right + "px",
            "padding-bottom": params.bottom + "px",
            "padding-left": params.left + "px"
        };
        $B.Dom.css(this.curImgTag, css);
        this.curImgTag = undefined;
    },
    imgBorderFn: function (css) {
        $B.Dom.css(this.curImgTag, css);
    },
    uploadFn: function (params) {
        if (params.url !== "") {
            let r = this._getDomRange();
            if (r.collapsed && r.startContainer.nodeType === 3) {
                let $s1 = r.startContainer.parentNode;
                let $img = this.createLinkA(params);
                let ret = this.splitWrapText($s1, r.startOffset, r.endOffset);
                let imgEL;
                if(Array.isArray(ret)){
                    $s1.style.display = "none";
                    let targetEL = $s1;                   
                    for (let i = 0; i < ret.length; i++) {
                        let el = ret[i];
                        $B.Dom.after(targetEL, el);
                        targetEL = el;
                        if ($B.Dom.hasClass(el, "_region_span")) {
                            $B.Dom.removeClass(el, "_region_span");
                            $B.Dom.addClass(el, "_hyper_link");
                            el.innerHTML = "";
                            imgEL = el;
                        }
                    }
                    $B.Dom.remove($s1);
                    $B.Dom.append(imgEL, $img);
                }else{
                    imgEL = ret;
                    imgEL.innerHTML="";
                    $B.Dom.append(imgEL, $img);
                    $B.Dom.removeClass(imgEL, "_region_span");
                }
                if (!imgEL.nextSibling) {
                    let $nextSp = UTILS.createSpanEl();
                    $B.Dom.after(imgEL, $nextSp);
                }
                if (!imgEL.previousSibling) {
                    let $nextSp = UTILS.createSpanEl();
                    $B.Dom.before(imgEL, $nextSp);
                }
                $B.Dom.attr(imgEL, { "contenteditable": false });
                setTimeout(() => {
                    this.move2start(imgEL.nextSibling);
                }, 1);
            } else {
                $B.alert(editCfg.label.availableInsert, 1.6);
            }
        }
    },
    focus:function(focusEnd){       
        if(focusEnd){
           this.move2end( this.$input.lastChild);
        }else{
            this.move2start( this.$input.firstChild);
        }
    },
    orderListFn:function(params){
        console.log(params);
        this.getFontIconBase64("#F7003E",30,"&#x26ab;");
    }, 
    unorderListFn:function(params){
        console.log(params);
    }
}); 
class KeditTools extends $B.BaseControl {
    constructor(editIns) {
        super();
        this.BUICTLS = [];
        this.$panels = [];
        this.cssMap = {};
        this.editIns = editIns;
        this.$wrap = $B.DomUtils.createEl("<div tabindex='0' style='z-index:1' class='k_box_size k_edit_tools_wrap'></div>");
        this.$tip = $B.DomUtils.createEl("<div style='width:auto;max-width:150px;position:absolute;display:none;' class='k_edit_tools_tip_wrapper' disabled='disabled'><div class='k_edit_tools_tip_caret'><i style='height:5px;' class='fa fa-up-dir'></i></div><div class='k_edit_tools_tip_text'></div></div>");
        this.regionMap = editCfg.regionMap ? editCfg.regionMap : {};
        this.createUi();
        $B.DomUtils.append(editIns.elObj, this.$wrap);
        this.bindEvents();
        $B.DomUtils.append(document.body, this.$tip);
        var _this = this;
        this.colorIns = editIns.getColorIns("toolbar",function(hex, opacity){
               if(this.tagName === "DIV"){
                    $B.DomUtils.css(this.lastChild, { "background-color": hex, opacity: opacity });
                }else{
                    $B.DomUtils.css(this, { "background-color": hex, opacity: opacity });
                }
                if(this.id === "_border_color"){ //段落边框颜色
                    _this.exeBorderCssFn();
                    return;
                }else if(this.id === "k_img_color"){//图片边框颜色
                    _this.exeImgBorderCssFn();
                    return;
                }            
                _this.editIns.execute(_this.editAPI, { color: hex, opacity: opacity }, this.lastChild);
        });
        setTimeout(() => {
            this.bindFocusEv(this.$wrap);
        }, 10);
    }
    /**
     * 回车键事件
     * **/
    onEditorMouseDown(){
        this.hidePanel();
    }
    /**
     * 绑定鼠标focus事件
     * **/
    bindFocusEv($el) {
        this.editIns.bindFocusEv($el);
    }
    /**
     * 绑定工具栏点击监听
     */
    bindEvents() {
        $B.DomUtils.click(this.$wrap, (e) => {
            this.editIns.callOffBrush();
            let el = e.target;
            let btn;
            while (el) {
                if ($B.DomUtils.hasClass(el, "k_edit_tools_wrap")) {
                    break;
                }
                if ($B.DomUtils.hasClass(el, "k_edit_tools_item")) {
                    btn = el;
                    break;
                }
                el = el.parentNode;
            }
            if (btn) {
                if(!$B.Dom.hasClass(btn,"k_edit_tools_disabled")){
                    this.callFn(btn);
                }                
            }
        });
    }
    /**
     * 调用点击处理函数，优先调用工具栏自身实现的处理函数，
     * 再次检查是否是一个Maker处理，否则调用编辑器的处理函数
     * **/
    callFn(btn) {
        let fn = $B.DomUtils.attribute(btn, "fn");
        let val = $B.DomUtils.attribute(btn, "val");
        this.editIns.hideAll();
        //优先执行工具栏自身的响应
        if (typeof this[fn] === "function") {
            this[fn](btn, val);
        } else {
            //需要工具栏自身提供响应的api
            let makeName = fn + "Maker";
            if (typeof this[makeName] === "function") {
                this.editAPI = fn;
                this[makeName](fn, btn);
            } else {
                this.editIns.execute(fn, val, btn);
            }
        }
    }
    pictureFnMaker(fn, btn){
        //先检测是否有可插入的位置
        let go = true;
        try{
            let r = this.editIns._getDomRange();
            go =  r.collapsed &&  r.startContainer.nodeType === 3 ;
        }catch(e){
            console.log(e);
            go = false;
        }
        if(!go){
            $B.alert(editCfg.label.availableInsert,1.6);
            return;
        }        
        let elkey = "$" + fn;
        let bodyKey = elkey + "_body";
        let $fb = this[bodyKey];
        let opts;
        if(!$fb){
            opts = {
                title: editCfg.label.insertImg,
                css:undefined,
                onCreated:($wap) => {
                    let $form = $B.DomUtils.createEl(editCfg.imageForm);
                    $fb = $form;
                    let css = "p{line-height:30px;padding-top:12px;} span.label{text-align:left;margin-left:10px;} p span{display:inline-block;}"
                            +".k_edit_img_pos{background:url("+editCfg.imgPos+") no-repeat;display:block;float:left;cursor:pointer;margin-left:12px;opacity:0.4;}"
                            +".pos_actived{opacity:1;}.k_edit_img_pos_right{height:17px;width:19px;background-position:0 0;margin-left:17px;}"
                            +".k_edit_img_pos_left{height:17px;width:19px;background-position:0 -17px;}.k_edit_img_pos_innser{height:17px;width:19px;background-position:0 -51px;}"
                            +".k_edit_img_pos_center{height:17px;width:19px;background-position:0 -34px;}#_submit_upload_{padding:3px 5px;}";

                    $B.createTextIfr($wap, $form, css, { height: '300px', width: '500px' });                    
                    this[bodyKey] = $form; 

                    let $top = $B.Dom.findbyId($fb,"_top_k_padding");
                    let $bottom = $B.Dom.findbyId($fb,"_bottom_k_padding"); 
                    let $left = $B.Dom.findbyId($fb,"_left_k_padding");
                    let $right = $B.Dom.findbyId($fb,"_right_k_padding");
                    let $width = $B.Dom.findbyId($fb,"_img_width");
                    let $height = $B.Dom.findbyId($fb,"_img_height");
                    let $href = $B.Dom.findbyId($fb,"_href_");
                    let $pos = $B.Dom.findbyId($fb,"_img_pos");

                    setTimeout(() => {
                        $B.DomUtils.attribute(this[elkey],{"hold":1});
                    }, 10);                  
                    let $upload = $B.Dom.findbyId($fb,"_file_upload_wrap");
                    let opt = {
                        timeout: 300, //超时时间 秒
                        onlyOne: true,
                        multiple: false, //是否可批量选择
                        immediate: false, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
                        accept: '.jpg,.jpeg,.gif,.bmp,.png',   // 可上传的文件类型 .xml,.xls,.xlsx,.png                       
                        error: function (res,err) { //错误回调                           
                            $B.error(editCfg.label.uploadError,1.6);
                            console.log(err);
                        } 
                    };                   
                    let onScussFn = this.editIns.opts.imgUpload.success;
                    $B.extendObjectFn(opt, this.editIns.opts.imgUpload);
                  
                    opt.success = (mesage, data, res)=>{
                        if(typeof data === "string"){
                            this.returnImg = data;
                        }else{
                            this.returnImg = data.url;
                            if(data.width){
                                $width.value = data.width;
                            }
                            if(data.height){
                                $height.value = data.height;
                            }
                        } 
                        if(onScussFn){
                            onScussFn(mesage, data, res);
                        }                        
                    };
                   
                    let uploadIns = new $B.Upload($upload ,opt); 
                    this.BUICTLS.push(uploadIns);
                    this.uploadIns = uploadIns;
                    let $localBtn = $B.Dom.findbyId($fb,"_local_upload_");  
                    let $remoteBtn = $B.Dom.findbyId($fb,"_remote_upload_"); 
                    let localForm = $B.Dom.findbyId($fb,"_local_upload_form");  
                    let rmoteForm = $B.Dom.findbyId($fb,"_remote_upload_form");  
                    let isLocal = true;            
                    let swdithFN = (e)=>{
                        $width.value = "";
                        $height.value = "";
                        let el = e.target;
                        if(el.id === "_local_upload_"){
                            localForm.style.display = "";
                            rmoteForm.style.display = "none";
                            $localBtn.style.background = "#666666";
                            $localBtn.style.color = "#fff";
                            $remoteBtn.style.background = "#fff";
                            $remoteBtn.style.color = "#666666";
                            isLocal = true;
                        }else{
                            localForm.style.display = "none";
                            rmoteForm.style.display = "";
                            $localBtn.style.background = "#fff";
                            $localBtn.style.color = "#666666";
                            $remoteBtn.style.background = "#666666";
                            $remoteBtn.style.color = "#fff";
                            isLocal = false;
                        }
                    };
                    $B.Dom.click($localBtn,swdithFN);
                    $B.Dom.click($remoteBtn,swdithFN);                    

                    let $submit = $B.Dom.findbyId($fb,"_submit_upload_");
                    $B.Dom.click($submit,(e)=>{  
                        let params = {
                            top: $B.getInputVal($top,0),
                            bottom: $B.getInputVal($bottom,0),
                            right: $B.getInputVal($right,0),
                            left: $B.getInputVal($left,0),
                            width: $B.getInputVal($width,0),
                            height: $B.getInputVal($height,0),
                            pos:$pos.value
                        };
                        if(isLocal){
                            params["url"] = this.returnImg;
                        }else{
                            params["url"] = $B.getInputVal($href);
                        }                  
                        this.hidePanel();                       
                        this.editIns.execute(fn, params);
                    });

                    $B.Dom.click($B.Dom.findbyId($fb,"k_edit_img_layout"),(e)=>{
                        let el = e.target;                       
                        if(el.nodeName === "A"){                         
                            $B.Dom.addClass(el,"pos_actived");
                            let p = $B.Dom.attr(el,"v");
                            $pos.value = p;
                            $B.Dom.forSiblings(el,(node)=>{
                                if(node.nodeName === "A"){
                                    $B.Dom.removeClass(node,"pos_actived");
                                }
                            });                            
                        }
                    });
                },
                onPanalClick: (e) => {
                    // console.log(e);
                }
            };            
        }
        this.createCommPanel(btn,elkey,opts); 
        this.uploadIns.clear(); 
        this.returnImg = "";
        return $fb;  
    }
    editImgMaker(fn, btn){
        let elkey = "$" + fn;
        let bodyKey = elkey + "_body";
        let $fb = this[bodyKey];
        let opts;
        if(!$fb){
            opts = {
                title: editCfg.label.editImg,
                css:undefined,
                onCreated:($wap) => {
                    let $form = $B.DomUtils.createEl(editCfg.imgEditForm);
                    $fb = $form;
                    let css = "p{line-height:30px;padding-top:12px;} span.label{text-align:left;margin-left:10px;} p span{display:inline-block;}"                          
                             +"#_submit_upload_{padding:3px 5px;}";

                    $B.createTextIfr($wap, $form, css, { height: '120px', width: '450px' });                    
                    this[bodyKey] = $form; 

                    let $top = $B.Dom.findbyId($fb,"_top_k_padding");
                    let $bottom = $B.Dom.findbyId($fb,"_bottom_k_padding"); 
                    let $left = $B.Dom.findbyId($fb,"_left_k_padding");
                    let $right = $B.Dom.findbyId($fb,"_right_k_padding");
                    let $width = $B.Dom.findbyId($fb,"_img_width");
                    let $height = $B.Dom.findbyId($fb,"_img_height");

                    setTimeout(() => {
                        $B.DomUtils.attribute(this[elkey],{"hold":1});
                    }, 10);         

                    let $submit = $B.Dom.findbyId($fb,"_submit_upload_");
                    $B.Dom.click($submit,(e)=>{  
                        let params = {
                            top: $B.getInputVal($top,0),
                            bottom: $B.getInputVal($bottom,0),
                            right: $B.getInputVal($right,0),
                            left: $B.getInputVal($left,0),
                            width: $B.getInputVal($width,0),
                            height: $B.getInputVal($height,0)
                        };                                    
                        setTimeout(()=>{
                            this.hidePanel();
                        },10);                       
                        this.editIns.execute(fn, params);
                    });
                },
                onPanalClick: (e) => {
                    // console.log(e);
                }
            };            
        }
        this.createCommPanel(btn,elkey,opts);        
        return $fb;  
    }
    borderImgMaker(fn, btn){
        let elkey = "$" + fn;
        let bodyKey = elkey + "_body";
        let $fb = this[bodyKey];
        let opts;
        if(!$fb){
            opts = {
                title: editCfg.label.borderImg,
                css:undefined,
                onCreated:($wap) => {
                    let $form = $B.DomUtils.createEl(editCfg.borderForm);
                    $fb = $form;                                    
                    this[bodyKey] = $form; 
                    $B.Dom.append($wap,$form); 
                    setTimeout(() => {
                        $B.DomUtils.attribute(this[elkey],{"hold":1});
                    }, 10);
                    let $submit = $B.Dom.findbyId($fb,"_cls_btn");   
                    let $pos = $B.Dom.findbyId($fb,"k_border_pos");
                    let $tyle = $B.Dom.findbyId($fb,"k_border_style");
                    let $size = $B.Dom.findbyId($fb,"k_border_size");
                    let $color = $B.Dom.findbyId($fb,"k_img_color");
                    let exeCuteFN = ()=>{
                        let prs = {
                            "border-top":"none",
                            "border-right":"none",
                            "border-bottom":"none",
                            "border-left":"none"
                        };
                        let bgColor = $B.DomUtils.css($color, "background-color");
                        let bstyle = $tyle.value;
                        let bsize = $size.value;
                        let childs = $pos.children;
                        for(let i =0 ;i < childs.length ;i++){
                            if($B.Dom.hasClass(childs[i],"activted")){
                                let key = "border-"+$B.Dom.attr(childs[i],"v");
                                prs[key] = bsize + " "+bstyle + " "+bgColor;
                            }
                        }
                        this.editIns.execute("imgBorderFn", prs);
                    };
                    this.exeImgBorderCssFn = exeCuteFN;
                    $B.Dom.click($submit,(e)=>{           
                        setTimeout(()=>{
                            this.hidePanel();
                        },10);   
                    });
                    $B.Dom.click($pos,(E)=>{
                        let el = E.target;                        
                        if($B.Dom.hasClass(el,"_border_pos")){
                            if($B.Dom.hasClass(el,"activted")){
                                el.style.backgroundColor = "#FFF";
                                $B.Dom.removeClass(el,"activted");
                            }else{
                                el.style.backgroundColor = "#93F5FA";
                                $B.Dom.addClass(el,"activted");
                            }  
                            exeCuteFN();                          
                        }                        
                    });                    
                    let onChangeFN = (e)=>{
                        exeCuteFN(); 
                    };
                    $B.Dom.change($tyle,onChangeFN);
                    $B.Dom.change($size,onChangeFN);                    
                    $B.Dom.click($color,(e)=>{
                        let btn = e.target;
                        if(this.colorIns.isShow() && btn === this.colorIns.target){
                            this.colorIns.hide();
                            return false;
                        }
                        let bgColor = $B.DomUtils.css(btn, "background-color");
                        let opacity = $B.DomUtils.css(btn, "opacity");
                        this.colorIns._callFnKey = "toolbar";
                        this.colorIns.setValue(bgColor, opacity);
                        this.colorIns.show(btn);  
                        setTimeout(()=>{
                            this.colorIns.target = btn;
                        },300);  
                        return false;
                    });
                },
                onPanalClick: (e) => {
                    // console.log(e);
                }
            };            
        }
        this.createCommPanel(btn,elkey,opts);  
        if(this.editIns.curImgTag){
            let borders =  UTILS.getBorder(this.editIns.curImgTag);            
            //联动当前img边框样式
            let $pos = $B.Dom.findbyId($fb,"k_border_pos");           
            let childs = $pos.children;
            let size = "1px",style = "solid",color = "#717171";
            let isDef = true;
            for(let i =0 ;i < childs.length ;i++){
                let k = "border-"+$B.Dom.attr(childs[i],"v");
                if(borders[k]){
                    $B.Dom.addClass(childs[i],"activted");
                    childs[i].style.backgroundColor = "#93F5FA";
                    if(isDef){
                       isDef = false;
                       let obj = UTILS.border2obj(borders[k],true);
                       size = obj.size;
                       style = obj.style;
                       color = obj.color;
                    }
                }else{
                    $B.Dom.removeClass(childs[i],"activted");
                    childs[i].style.backgroundColor = "#fff";
                }
            }
            let $tyle = $B.Dom.findbyId($fb,"k_border_style");
            let $size = $B.Dom.findbyId($fb,"k_border_size");
            let $color = $B.Dom.findbyId($fb,"k_img_color"); 
            $B.setSelectValue($size,size);
            $B.setSelectValue($tyle,style);
            $color.style.backgroundColor = color;
        }     
        return $fb; 
    }
    linkFnMaker(fn, btn){       
        let elkey = "$" + fn;
        let bodyKey = elkey + "_body";
        let $fb = this[bodyKey];
        let opts;
        if(!$fb){
            opts = {
                title: editCfg.label.insertLink,
                css:undefined,
                onCreated:($wap) => {
                    let $form = $B.DomUtils.createEl(editCfg.linkForm);
                    $fb = $form;
                    $B.createTextIfr($wap, $form, "p{line-height:30px;padding-top:12px;} span.label{text-align:left;margin-left:10px;} p span{display:inline-block;}", { height: '160px', width: '350px' });                    
                    this[bodyKey] = $form; 
                    let $btn = $B.Dom.findbyId($form,"okbtn");
                    $B.Dom.click($btn,(e)=>{
                        let $target = $B.Dom.findbyId($form,"_target_");
                        let $addr = $B.Dom.findbyId($form,"_addr_url");
                        let $name =  $B.Dom.findbyId($form,"_link_name");
                        let isBlank = $B.Dom.attr($target,"checked") === true;
                        let addr = $B.trimFn( $addr.value);
                        let name = $B.trimFn($name.value);                    
                        this.hidePanel();
                        if(addr !== "" && name !== ""){
                            let params = {name:name,addr:addr,isBlank:isBlank};                           
                            this.editIns.linkFn(params);
                        }
                    });
                },
                onPanalClick: (e) => {
                    // console.log(e);
                }
            };            
        }
        this.createCommPanel(btn,elkey,opts);  
        this.editIns.onOpenLinkPanel($fb);
        return $fb;     
    } 
    uploadFnMaker(fn, btn){
                //先检测是否有可插入的位置
                let go = true;
                try{
                    let r = this.editIns._getDomRange();
                    go =  r.collapsed &&  r.startContainer.nodeType === 3 ;
                }catch(e){
                    console.log(e);
                    go = false;
                }
                if(!go){
                    $B.alert(editCfg.label.availableInsert,1.6);
                    return;
                }        
                let elkey = "$" + fn;
                let bodyKey = elkey + "_body";
                let $fb = this[bodyKey];
                let opts;
                if(!$fb){
                    opts = {
                        title: editCfg.label.insertFile,
                        css:undefined,
                        onCreated:($wap) => {
                            let $form = $B.DomUtils.createEl(editCfg.fileForm);
                            $fb = $form;
                            let css = "p{line-height:30px;padding-top:12px;} span.label{text-align:left;margin-left:10px;} p span{display:inline-block;}"
                                    +".k_edit_img_pos{background:url("+editCfg.imgPos+") no-repeat;display:block;float:left;cursor:pointer;margin-left:12px;opacity:0.4;}"
                                    +".pos_actived{opacity:1;}.k_edit_img_pos_right{height:17px;width:19px;background-position:0 0;margin-left:17px;}"
                                    +".k_edit_img_pos_left{height:17px;width:19px;background-position:0 -17px;}.k_edit_img_pos_innser{height:17px;width:19px;background-position:0 -51px;}"
                                    +".k_edit_img_pos_center{height:17px;width:19px;background-position:0 -34px;}#_submit_upload_{padding:3px 5px;}";
        
                            $B.createTextIfr($wap, $form, css, { height: '160px', width: '500px' });                    
                            this[bodyKey] = $form; 
        
                            let $url = $B.Dom.findbyId($fb,"_addr_url");                         
                            let $name = $B.Dom.findbyId($fb,"file_name");                          
        
                            setTimeout(() => {
                                $B.DomUtils.attribute(this[elkey],{"hold":1});
                            }, 10);                  
                            let $upload = $B.Dom.findbyId($fb,"_file_upload_wrap");
                            let opt = {
                                timeout: 300, //超时时间 秒
                                onlyOne: true,
                                multiple: false, //是否可批量选择
                                immediate: false, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
                                error: function (res,err) { //错误回调                           
                                    $B.error(editCfg.label.uploadError,1.6);
                                    console.log(err);
                                } 
                            };                   
                            let onScussFn = this.editIns.opts.fileUpload.success;
                            $B.extendObjectFn(opt, this.editIns.opts.fileUpload);
                          
                            opt.success = (mesage, data, res)=>{
                                let fileName;
                                if(typeof data === "string"){
                                    this.returnFile = data;
                                }else{
                                    this.returnFile = data.url;
                                    if(data.labelName){
                                        fileName = data.labelName;
                                    }
                                }
                                if(!fileName){
                                    let tmps = this.returnFile.split("/");
                                    fileName = tmps[tmps.length - 1];
                                }     
                                $name.value = fileName;                           
                                if(onScussFn){
                                    onScussFn(mesage, data, res);
                                }                        
                            };
                           
                            let uploadIns = new $B.Upload($upload ,opt); 
                            this.BUICTLS.push(uploadIns);
                            this.uploadFileIns = uploadIns;
                            let $localBtn = $B.Dom.findbyId($fb,"_local_upload_");  
                            let $remoteBtn = $B.Dom.findbyId($fb,"_remote_upload_"); 
                            let localForm = $B.Dom.findbyId($fb,"_local_upload_form");  
                            let rmoteForm = $B.Dom.findbyId($fb,"_remote_upload_form");  
                            let isLocal = true;            
                            let swdithFN = (e)=>{
                                let el = e.target;
                                if(el.id === "_local_upload_"){
                                    localForm.style.display = "";
                                    rmoteForm.style.display = "none";
                                    $localBtn.style.background = "#666666";
                                    $localBtn.style.color = "#fff";
                                    $remoteBtn.style.background = "#fff";
                                    $remoteBtn.style.color = "#666666";
                                    isLocal = true;
                                }else{
                                    localForm.style.display = "none";
                                    rmoteForm.style.display = "";
                                    $localBtn.style.background = "#fff";
                                    $localBtn.style.color = "#666666";
                                    $remoteBtn.style.background = "#666666";
                                    $remoteBtn.style.color = "#fff";
                                    isLocal = false;
                                }
                            };
                            $B.Dom.click($localBtn,swdithFN);
                            $B.Dom.click($remoteBtn,swdithFN);                    
        
                            let $submit = $B.Dom.findbyId($fb,"_submit_upload_");
                            $B.Dom.click($submit,(e)=>{  
                                let params = {
                                    name : $B.getInputVal($name),                               
                                };
                                if(isLocal){
                                    params["url"] = this.returnFile;
                                }else{
                                    params["url"] = $B.getInputVal($url);
                                }                  
                                this.hidePanel();                       
                                this.editIns.execute(fn, params);
                            });                            
                        },
                        onPanalClick: (e) => {
                            // console.log(e);
                        }
                    };            
                }
                this.createCommPanel(btn,elkey,opts); 
                this.uploadFileIns.clear(); 
                this.returnFile = "";
                return $fb;  
    }    
    emotionFnMaker(fn, btn){

    }
    insertIconFnMaker(fn, btn){

    }
    /**
     * 插入浮动文本窗口创建
     * **/
    insertFloatFnMaker(fn, btn) {
    }
    /**
     * 插入表格窗口窗口
     * **/
    insertTableFnMaker(fn, btn) {
        let elkey = "$" + fn;
        let bodyKey = elkey + "_body";
        let $fb = this[bodyKey];
        let opts;
        if(!$fb){
            opts = {
                title: editCfg.label.insertTable,
                css:undefined,
                onCreated:($wap) => {
                    let $form = $B.DomUtils.createEl("<table style='width:166px;' class='k_edit_table_set'></table>");
                    let tdArray = [];
                    for (let i = 0, len = 15; i < len; ++i) {
                        var $tr = $B.DomUtils.createEl("<tr row='" + i + "'></tr>");
                        for (var j = 0, jlen = 15; j < jlen; ++j) {                            
                            let $td = $B.DomUtils.append($tr,"<td col='" + j + "'></td>");
                            tdArray.push($td);
                        }
                        $B.DomUtils.append($form,$tr);
                    }
                    $B.DomUtils.append($wap,$form);
                    let tip = editCfg.label.insertTableTip.replace("x","0").replace("y","0");
                    let $tip = $B.DomUtils.createEl("<p style='text-align:left'>"+tip+"</p>");
                    $B.DomUtils.append($wap,$tip);
                    this[bodyKey] = $form;
                    $B.DomUtils.mousemove($form,(e)=>{
                        $B.DomUtils.removeClass(tdArray,"selectd");
                        let td = e.target;
                        $B.DomUtils.addClass(td,"selectd");
                        let col = parseInt( $B.DomUtils.attribute(td,"col"));                       
                        if(col !== NaN){
                            let row = parseInt( $B.DomUtils.attribute(td.parentNode,"row"));
                            let preEl = td.previousSibling;
                            while(preEl){
                                $B.DomUtils.addClass(preEl,"selectd");
                                preEl = preEl.previousSibling;
                            }
                            let tr = td.parentNode.previousSibling;
                            while(tr){
                                let childs = tr.children;
                                for(let i =0 ; i < childs.length ;i++){
                                    $B.DomUtils.addClass(childs[i],"selectd");
                                    if(i === col){
                                        break;
                                    }
                                }
                                tr = tr.previousSibling;
                            }
                            tip = editCfg.label.insertTableTip.replace("x",row+1).replace("y",col+1);
                            $tip.innerText = tip;
                        }
                    });
                    $B.DomUtils.click($form,(e)=>{
                        //console.log("exe insert table......");
                        $B.DomUtils.removeClass(tdArray,"selectd");
                        var td = e.target;
                        let col = parseInt( $B.DomUtils.attribute(td,"col")) + 1;
                        let row = parseInt( $B.DomUtils.attribute(td.parentNode,"row")) + 1;
                        this.hidePanel();
                        this.editIns.execute("insertTableFn", {row:row,col:col});          
                    });
                },
                onPanalClick: (e) => {
                    // console.log(e);
                }
            };            
        }
        this.createCommPanel(btn,elkey,opts);
        let trs = this[bodyKey].children;
        for(let i = 0 ; i < trs.length ;i++){
            let tds = Array.from(trs[i].children);
            $B.DomUtils.removeClass(tds,"selectd");
        }
    }
    /**
     * 段落Panel窗口创建
     * **/
    paragraphFnMaker(fn, btn) {     
        //console.log(fn,btn);    
        let elkey = "$" + fn;
        let bodyKey = elkey + "_body";
        let $fb = this[bodyKey];
        let opts;
        var _this = this;
        if(!$fb){
            opts = {
                title: editCfg.label.paragraph,
                css:undefined,
                onCreated:($wap) => {
                    let $form = $B.DomUtils.createEl(editCfg.paragraphForm);
                    $B.createTextIfr($wap, $form, ".borderAct{background:#05F5FF !important;}", { height: '240px', width: '450px' });
                    this[bodyKey] = $form;  
                    setTimeout(()=>{
                        $B.DomUtils.attribute(this[elkey],{"hold":1});
                    },1);                      
                    let inuptFn = function(e){
                        let elid = e.target.id;
                        let val = e.target.value;
                        if(!/^\d+$/.test(val)){
                            return;
                        }                       
                        let css;
                        if(elid === "_indent_"){
                            _this.editIns.execute("pindentFn", {indent: parseInt(val) });                         
                        }else if(elid === "txt_line_h"){
                            _this.editIns.execute("plineHeight", {"line-height": val });
                        }else if(elid === "_pdding-top_"){
                            css = {"padding-top":val+"px"};
                        }else if(elid === "_pdding-bottom_"){
                            css = {"padding-bottom":val+"px"};
                        }else if(elid === "_padding-left_"){
                            css = {"padding-left":val+"px"};
                        }else if(elid === "_padding-right_"){
                            css = {"padding-right":val+"px"};
                        }
                        if(css){
                            _this.editIns.execute("ppadding", css);
                        }
                    };
                    let $borderStyle,$borderSize,$borderColor,$borderPos;

                    let  exeBorderCssFn = function(){                        
                        let params = {};
                        let el = $borderPos.firstChild;
                        let bstyle = $borderStyle.value;
                        let bsize = $borderSize.value;
                        let bcolor = $B.DomUtils.css($borderColor,"background-color");
                        let v =  bsize+" "+ bstyle+" " + bcolor;
                        if($B.DomUtils.hasClass(el,"borderAct")){
                            params["border-left"] = v;
                        }
                        el = el.nextSibling;
                        if($B.DomUtils.hasClass(el,"borderAct")){
                            params["border-top"] = v;
                        }
                        el = el.nextSibling;
                        if($B.DomUtils.hasClass(el,"borderAct")){
                            params["border-right"] = v;
                        }
                        el = el.nextSibling;
                        if($B.DomUtils.hasClass(el,"borderAct")){
                            params["border-bottom"] = v;
                        }
                        _this.editIns.execute("pborderFn", params);
                    };
                    _this.exeBorderCssFn = exeBorderCssFn;//拾色器触发
                    let $txtLineH = $B.DomUtils.findbyId($form,"#txt_line_h");
                    let selectedFn =function(e){
                        let elid = e.target.id;                       
                        if(elid === "_line-height_"){
                            if(e.target.value !== ""){
                                let val = parseFloat( e.target.value);
                                _this.editIns.execute("plineHeight", {"lineR": val },$txtLineH);
                            }
                        }else{//边框修饰
                            exeBorderCssFn();
                        }
                    };
                    let $indent = $B.DomUtils.findbyId($form,"#_indent_");  
                    $B.DomUtils.input($indent,inuptFn);
                   
                    $borderStyle = $B.DomUtils.findbyId($form,"#_border_style");
                    $B.DomUtils.change($borderStyle,selectedFn);
                    $borderSize = $B.DomUtils.findbyId($form,"#_border_size");
                    $B.DomUtils.change($borderSize,selectedFn);
                   
                    let $paddingTop = $B.DomUtils.findbyId($form,"#_pdding-top_"); 
                    $B.DomUtils.input($paddingTop,inuptFn);
                    let $paddingBottom = $B.DomUtils.findbyId($form,"#_pdding-bottom_");
                    $B.DomUtils.input($paddingBottom,inuptFn);
                    let $paddingLeft = $B.DomUtils.findbyId($form,"#_padding-left_");
                    $B.DomUtils.input($paddingLeft,inuptFn);
                    let $paddingRight = $B.DomUtils.findbyId($form,"#_padding-right_");
                    $B.DomUtils.input($paddingRight,inuptFn);
                    let $lineHOpt = $B.DomUtils.findbyId($form,"#_line-height_"); 
                    $B.DomUtils.change($lineHOpt,selectedFn);
                  
                    $B.DomUtils.input($txtLineH,inuptFn);

                    let colorFn = function(e){
                        let el = e.target;
                        while(el){
                            if(el.tagName === "SPAN"){
                                break;
                            }
                            el = el.parentNode;
                        }
                        let id = el.id;
                        let top = 35 , left =0 ;                       
                        if(id === "_border_color"){//边框颜色
                            //边框颜色需要组合边框其他参数
                            //this.editAPI = "pcolorFn";
                        }else if(id === "_font_color"){
                            _this.editAPI = "pcolorFn";
                        }else if(id === "_bg_color"){
                            _this.editAPI = "pbackground";
                        }        
                        let $grp = _this["$paragraphFn"];                
                        let ofs = $B.DomUtils.offset($grp);
                        ofs.top = ofs.top + top;
                        ofs.left = ofs.left + left;                      
                        _this.showColorPicker(el,ofs);
                        return false;
                    };

                    $borderColor = $B.DomUtils.findbyId($form,"#_border_color");
                    let $fontcolor =  $B.DomUtils.findbyId($form,"#_font_color");
                    let $bgColor = $B.DomUtils.findbyId($form,"#_bg_color");
                    $B.DomUtils.click($borderColor,colorFn);
                    $B.DomUtils.click($fontcolor,colorFn);
                    $B.DomUtils.click($bgColor,colorFn);

                    $borderPos = $B.DomUtils.findbyId($form,"#_border_pos");
                    $B.DomUtils.click( $borderPos ,(e)=>{     
                        if(e.target.id !== "_border_pos"){
                            if($B.DomUtils.hasClass(e.target,"borderAct")){
                                $B.DomUtils.removeClass(e.target,"borderAct");
                            }else{
                                $B.DomUtils.addClass(e.target,"borderAct");
                            }
                            exeBorderCssFn();
                        } 
                    });
                },
                onPanalClick: (e) => {
                   // console.log(e);
                }
            };            
        }
        let $panel = this.createCommPanel(btn,elkey,opts); 
        $panel.id = "paragraph_panel"; 
        $fb = this[bodyKey];
        let cssMap = this.cssMap;
        if (cssMap["letter-spacing"]) { 
          this.rectiveGraphUI($fb,cssMap);
        }       
        if(btn && btn.openFlag){
            if(btn.openFlag === "table"){
                this.editIns.tableIns.activedLinePELS();//高亮当前选择的段落
            }
        }else{
            this.editIns.activedLinePELS();//高亮当前选择的段落
        }    
        return $fb;    
    }
    rectiveGraphUI($fb,cssMap){
        let $borderPos = $B.DomUtils.findbyId($fb,"#_border_pos");
        let $borderStyle = $B.DomUtils.findbyId($fb,"#_border_style");
        let $borderSize = $B.DomUtils.findbyId($fb,"#_border_size");
        let $borderColor = $B.DomUtils.findbyId($fb,"#_border_color");  
        let $bleft =  $borderPos.firstChild;
        let bmap = {
            size:undefined,
            style:undefined,
            color:undefined
        };
        if(cssMap["border-left"]){
           $B.DomUtils.addClass($bleft,"borderAct");
           let obj = UTILS.border2obj(cssMap["border-left"]); 
           UTILS.setBorderMap(bmap, obj );             
        }else{
           $B.DomUtils.removeClass($bleft,"borderAct");
        }
        if(cssMap["border-top"]){
            $B.DomUtils.addClass($bleft.nextSibling,"borderAct");
            let obj = UTILS.border2obj(cssMap["border-left"]);
            UTILS.setBorderMap(bmap, obj );
        }else{
            $B.DomUtils.removeClass($bleft.nextSibling,"borderAct");
        }
        if(cssMap["border-right"]){
            $B.DomUtils.addClass($bleft.nextSibling.nextSibling,"borderAct");
            let obj = UTILS.border2obj(cssMap["border-right"]);
            UTILS.setBorderMap(bmap, obj );
        }else{
            $B.DomUtils.removeClass($bleft.nextSibling.nextSibling,"borderAct");
        }
        if(cssMap["border-bottom"]){
            $B.DomUtils.addClass($bleft.nextSibling.nextSibling.nextSibling,"borderAct");
            let obj = UTILS.border2obj(cssMap["border-bottom"]);
            UTILS.setBorderMap(bmap, obj );
        }else{
            $B.DomUtils.removeClass($bleft.nextSibling.nextSibling.nextSibling,"borderAct");
        }
        if(bmap.size){
            bmap.size = bmap.size+"px";
            let childs = $borderSize.children;
            for(let i = 0 ;i < childs.length ;i++){
                if(childs[i].value === bmap.size){
                    $B.DomUtils.attribute(childs[i],{"selected":true});
                }else{
                    $B.DomUtils.attribute(childs[i],{"selected":false});
                }                    
            }
        }          
        if(bmap.style){
            let childs = $borderStyle.children;
            for(let i = 0 ;i < childs.length ;i++){
                if(childs[i].value === bmap.style){
                    $B.DomUtils.attribute(childs[i],{"selected":true});
                }else{
                    $B.DomUtils.attribute(childs[i],{"selected":false});
                }                    
            }
        }
        if(bmap.color){
            $borderColor.style.backgroundColor = bmap.color;
        }
        //段落背景色
        let $bgcolor = $B.DomUtils.findbyId($fb,"#_bg_color");          
        if(cssMap.pbackgorund){
            $bgcolor.style.backgroundColor = cssMap.pbackgorund;
        }
        //字体颜色
        let $fontcolor =  $B.DomUtils.findbyId($fb,"#_font_color");   
        $fontcolor.style.backgroundColor = cssMap.color;

        //行高，边距，缩进
        let $indent = $B.DomUtils.findbyId($fb,"#_indent_");              
        let $paddingTop = $B.DomUtils.findbyId($fb,"#_pdding-top_"); 
        let $paddingBottom = $B.DomUtils.findbyId($fb,"#_pdding-bottom_");
        let $paddingLeft = $B.DomUtils.findbyId($fb,"#_padding-left_");
        let $paddingRight = $B.DomUtils.findbyId($fb,"#_padding-right_");
        let $lineHOpt = $B.DomUtils.findbyId($fb,"#_line-height_"); 
        let $txtLineH = $B.DomUtils.findbyId($fb,"#txt_line_h");
       
        $indent.value = cssMap.indent;
        $paddingTop.value = cssMap["padding-top"];
        $paddingBottom.value = cssMap["padding-bottom"];
        $paddingLeft.value = cssMap["padding-left"];
        $paddingRight.value = cssMap["padding-right"];
        $txtLineH.value = cssMap["line-height"];
        let childs = $lineHOpt.children;
        let r = cssMap["lhrate"] + "";
        let emptyOpt,hasFiled;
        for(let i = 0 ;i < childs.length ;i++){
            if(childs[i].value === r){
                $B.DomUtils.attribute(childs[i],{"selected":true});
                hasFiled = true;
            }else{
                $B.DomUtils.attribute(childs[i],{"selected":false});
            }
            if(childs[i].value === ""){
                emptyOpt = childs[i];
            }
        }
        if(!hasFiled){
            $B.DomUtils.attribute(emptyOpt,{"selected":true});
        } 
    }
    /**
     * 文字间距窗口创建
     * **/
    fontSpaceFnMaker(fn, btn) {
        let elkey = "$" + fn;
        let bodyKey = elkey + "_body";
        let $fb = this[bodyKey];
        let opts;
        if(!$fb){
            opts = {
                title: editCfg.label.wordspace,
                css:undefined,
                onCreated:($wap) => {
                    let $form = $B.DomUtils.createEl(editCfg.fontSpaceForm);
                    $B.createTextIfr($wap, $form, "p{line-height:30px;padding-top:12px;} span.label{text-align:left;margin-left:10px;} p span{display:inline-block;}", { height: '115px', width: '170px' });
                    let clickTags = $B.DomUtils.findByClass($form, "ev");
                    $B.DomUtils.click(clickTags, (e) => {
                        let el = e.target;
                        if (el.tagName === "svg") {
                            el = el.parentNode;
                        }
                        let $p =  el.parentNode;
                        let $forP = $B.DomUtils.findbyId($p.previousSibling,"for_p");
                        let $in = $p.nextSibling.firstChild.nextSibling.firstChild;
                        if(/^\d+$/.test($in.value)){
                            let v = parseInt($in.value);
                            if ($B.DomUtils.hasClass(el, "reduce")) {
                                v--;
                            } else if ($B.DomUtils.hasClass(el, "addplus")) {
                                v++;
                            } else {
                                v = 0;
                            }
                            $in.value = v;
                            let isforp =  $forP.checked ? true : false;
                            this.editIns.execute(fn,{"letter-spacing":v+"px","forp":isforp});
                        }
                    });
                    let btn = $B.DomUtils.findbyId($form, "surebtn");
                    $B.DomUtils.click(btn, (e) => {
                        let $forP = $B.DomUtils.findbyId(e.target.parentNode.parentNode.previousSibling.previousSibling,"for_p");
                        let isforp =  $forP.checked ? true : false;
                        let v = e.target.parentNode.previousSibling.firstChild.value;
                        if(/^\d+$/.test(v)){
                            this.editIns.execute(fn,{"letter-spacing":v+"px","forp":isforp});
                        }                
                    });
                    this[bodyKey] = $form;
                },
                onPanalClick: (e) => {
                    // console.log(e);
                }
            };            
        }
        this.createCommPanel(btn,elkey,opts);
        $fb = this[bodyKey];
        if (this.cssMap["letter-spacing"]) {                      
            let $input = $B.DomUtils.findbyId($fb, "txtinput");
            let $pradio = $B.DomUtils.findbyId($fb,"for_p");
            let $sradio = $B.DomUtils.findbyId($fb,"for_s");
            $input.value = this.cssMap["letter-spacing"];
            if(this.editIns.hasRegion()){
                $B.DomUtils.attribute($pradio,{checked:false});
                $B.DomUtils.attribute($sradio,{checked:true});
            }else{
                $B.DomUtils.attribute($pradio,{checked:true});
                $B.DomUtils.attribute($sradio,{checked:false});
            }
        }
    }
    /**
     * 背景色窗口窗口
     * **/
    backgroundColorFnMaker(fn, btn) {
        this.showColorPicker(btn.lastChild);  
    }
    /**
     * 字体颜色窗口创建
     * **/
    fontColorFnMaker(fn, btn) {
        this.showColorPicker(btn.lastChild); 
    }
    /**
     * 显示拾色器
     * **/
    showColorPicker(btn,ofs){
        if(this.colorIns.isShow() && btn === this.colorIns.target){
            this.colorIns.hide();
            return ;
        }
        var bgColor = $B.DomUtils.css(btn, "background-color");
        var opacity = $B.DomUtils.css(btn, "opacity");
        this.colorIns._callFnKey = "toolbar";
        this.colorIns.setValue(bgColor, opacity);
        this.colorIns.show(btn,ofs);  
        setTimeout(()=>{
            this.colorIns.target = btn;
        },300);            
    }
    /**
     * 拾色器按钮ui渲染
     * **/
    _appendColorUI(btn, fn) {
        let $color = $B.DomUtils.createEl('<span class="k_box_size" style="border:1px solid #A0A0A0; display:inline-block;height: 5px;width: 100%;position: absolute;background: red;bottom: -3px;left: 0;"></span>');
        $B.DomUtils.append(btn, $color);
        if (fn === "fontColorFn") {
            $color.style.backgroundColor = "#000000";
        } else if (fn === "backgroundColorFn") {
            $color.style.backgroundColor = "#ffffff";
        }
        return $color;
    }
    /**
     * 获取工具栏高度
     * **/
    getHeight() {
        var h = $B.DomUtils.outerHeight(this.$wrap);
        return h;
    }
    /**
     * 当面板被隐藏后的回调
     * **/
    onPanelClosed(el){     
        if(el.id === "paragraph_panel"){
            this.editIns.unactivedLinePELS();
            this.editIns.tableIns.unactivedLinePELS();
        }
    }
    /** 
     * 绑定面板事件，点击，鼠标移出监听
     * 当传值clickFn时候注册点击监听
     * **/
    bindPanelEvents(el, clickFn) {
        if (!this.dlListEvents) {
            this.dlListEvents = {
                mouseleave: (e) => {
                    if($B.DomUtils.attribute(e.target,"hold")){
                        return;
                    }                   
                    this.hidePanel();
                }
            };
            if (clickFn) {
                this.dlListEvents["click"] = clickFn;
            }
        }
        $B.DomUtils.bind(el, this.dlListEvents);
    }
    /** 
     * 获取面板元素对象
     * **/
    getPanelEl() {
        return UTILS.getPanelEl();
    }
    /**
     * 创建工具栏UI
     * **/
    createUi() {
        let events = {
            mouseenter: (e) => {
                let title = $B.DomUtils.attribute(e.target, "_title");
                let ofs = $B.DomUtils.offset(e.target);
                let h = $B.DomUtils.outerHeight(e.target);
                ofs.top = ofs.top + h;
                this.$tip.lastChild.innerText = title;
                this.$tip.style.top = ofs.top + "px";
                this.$tip.style.left = ofs.left + "px";
                this.$tip.style.display = "";
                this.hidePanel();
            },
            mouseleave: (e) => {
                this.$tip.style.display = "none";
            }
        };
        /**单击列表事件**/
        let clickFN = (e) => {
            this.editIns.callOffBrush();
            let el = e.target;
            while (el) {
                if ($B.DomUtils.hasClass(el, "k_edit_tools_item")) {
                    break;
                }
                el = el.parentNode;
            }
            let _key = $B.DomUtils.attribute(el, "fn");
            let elkey = "$" + _key;
            if (!this[elkey]) {
                this[elkey] = this.getPanelEl();
                let $wap = this[elkey].lastChild;
                let arr = e.opts;
                let fus = $B.Dom.attr(el,"focus");
                if(fus){
                    fus = 'focus="1"';
                }
                for (let i = 0; i < arr.length; i++) {
                    let lbl = arr[i].label;
                    if(arr[i].value.indexOf("fa-") === 0){
                        lbl = "<i class='fa "+arr[i].value+"' style='padding-right:4px;'></i>"+lbl;
                    }
                    let $it = $B.DomUtils.append($wap, '<div '+fus+' fn="' + _key + '" val="' + arr[i].value + '" tabindex="0" style="" class="k_edit_tools_drop_item item" _focus="true">' + lbl + '</div>');
                    let css = {};
                    if (_key === "fontFamilyFn") {
                        css["font-family"] = arr[i].value;
                    } else if (_key === "fontSizeFn") {
                        css["font-size"] = arr[i].value;
                    } else if (_key === "fontTitleFn") {
                        css["font-size"] = arr[i].value;
                    }
                    $B.DomUtils.css($it, css);
                }
                $B.DomUtils.append(document.body, this[elkey]);
                this.$panels.push(this[elkey]);
                this.bindPanelEvents(this[elkey], (e) => {
                    let node = e.target;
                    let tg;
                    while (node) {
                        if ($B.DomUtils.hasClass(node, "k_edit_tools_drop_item_wrap")) {
                            break;
                        }
                        if ($B.DomUtils.hasClass(node, "k_edit_tools_drop_item")) {
                            tg = node;
                            break;
                        }
                        node = node.parentNode;
                    }
                    if (tg) {
                        let val = tg.innerText;
                        let fn = $B.Dom.attr(tg,"fn");
                        if(fn !== "orderListFn" && fn !== "unorderListFn"){
                            this.$curListFireBtn.firstChild.innerText = val;
                        }
                        this.callFn(tg);
                    }
                });
                this.bindFocusEv(this[elkey]);
            }
            if (!e._init) {
                this.showPanel(elkey, el);
            }
            return false;
        };
        var tools = editCfg.tools;        
        this.btnElMap = {};
        for (let i = 0; i < tools.length; i++) {
            let it = tools[i];
            if (it.region) {
                this.regionMap[it.fn] = true;
            }
            let btn = $B.DomUtils.createEl("<div fn='" + it.fn + "' unbindcolorev='1' style='padding-bottom:2px;cursor:pointer;position:relative;' tabindex='0' _title='" + it.label + "' class='k_box_size k_edit_tools_item'><i class='fa " + it.icon + " _e_btn_'></i></div>");
            if(it.fn === "undoFn" || it.fn === "redoFn"){
                $B.Dom.addClass(btn,"k_edit_tools_disabled");
            }
            this.btnElMap[it.fn] = btn;
            $B.DomUtils.append(this.$wrap, btn);
            $B.DomUtils.bind(btn, events);
            if(it.focus){
                $B.Dom.attr(btn,{"focus":1});
            }
            if (it.opts) { //存在下拉列表
                //console.log("下拉列表");
                if(it.fn !== "orderListFn" && it.fn !== "unorderListFn"){
                    $B.DomUtils.prepend(btn, "<span label='" + it.label + "'>" + it.label + "</span>");
                }
                $B.DomUtils.click(btn, clickFN);
                clickFN({ target: btn, _init: true, opts: it.opts });
            } else if (it.fn.indexOf("ColorFn") > 0) {
                this._appendColorUI(btn, it.fn);
            }
        }
    }
    /**
     * 显示panel
     * elKey: key
     * el: 可以是触发显示的元素，可以是位置对象
     * **/
    showPanel(elkey, el) {
        let ofs;
        if($B.DomUtils.isElement(el)){
            ofs = $B.DomUtils.offset(el);
            let h = $B.DomUtils.outerHeight(el);
            ofs.top = ofs.top + h + 6;
            this.$curListFireBtn = el;
        }else{
            ofs = el;
        }  
        this[elkey].style.display = "block";
        this[elkey].style.top = "-2000px";
        let w = $B.DomUtils.width(this[elkey]) + 3;
        let bw = $B.DomUtils.width(document.body);
        let diff = w + ofs.left - bw;
        if(diff > 0){
            ofs.left = ofs.left - diff;
            this[elkey].firstChild.firstChild.style.paddingLeft = diff+"px";
        }else{
            this[elkey].firstChild.firstChild.style.paddingLeft = "0px";
        }
        this[elkey].style.top = ofs.top + "px";
        this[elkey].style.left = ofs.left + "px";        
        this.$curOpenPanel = this[elkey];        
    }
    /**
     * 隐藏当前打开的panel
     * **/
    hidePanel(){
        if(this.$curOpenPanel){
            this.$curOpenPanel.style.display = "none";
            this.onPanelClosed(this.$curOpenPanel);            
            this.$curOpenPanel = undefined;
        }
    }
    /**
     * 创建通用panel
     * ***/
    createCommPanel(btn,elkey, opts) {        
        if (!this[elkey]) {
            if(!opts){
                opts = {};
            }
            opts.onClosed = ($el)=>{
                this.$curOpenPanel = undefined;
                this.$curListFireBtn = undefined;
                this.onPanelClosed($el);
            };
            this[elkey] = UTILS.createCommPanel(opts);
            this.$panels.push(this[elkey]);
            this.bindPanelEvents(this[elkey], opts.onPanalClick);
            this.bindFocusEv(this[elkey]);
        }
        this.showPanel(elkey, btn);
        return this[elkey];
    }
    /**
     * 判定按钮对应的处理函数是否需要选区
     * **/
    needRegion(fn) {
        return this.regionMap[fn];
    }
    /**联动工具栏**/
    reactiveUI(cssMap) {
        this.cssMap = cssMap;
        if (cssMap["letter-spacing"] === "normal" || !cssMap["letter-spacing"]) {
            cssMap["letter-spacing"] = "0";
        } else if(cssMap["letter-spacing"]) {
            cssMap["letter-spacing"] = cssMap["letter-spacing"].replaceAll("px", "");
        }      
        let $bold = this.btnElMap["boldFn"];
        if (cssMap["font-weight"] === "400") {
            $B.DomUtils.removeClass($bold, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.addClass($bold, "k_edit_tools_hlight");
        }
        let $italic = this.btnElMap["italicFn"];
        if (cssMap["font-style"] === "normal") {
            $B.DomUtils.removeClass($italic, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.addClass($italic, "k_edit_tools_hlight");
        }
        let $underline = this.btnElMap["underlineFn"];
        let txtDecriVal = cssMap["text-decoration"];
        if (txtDecriVal && txtDecriVal.indexOf("underline") >= 0) {
            $B.DomUtils.addClass($underline, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.removeClass($underline, "k_edit_tools_hlight");
        }
        let $strikethrough = this.btnElMap["strikethroughFn"];
        if (txtDecriVal && txtDecriVal.indexOf("line-through") >= 0) {
            $B.DomUtils.addClass($strikethrough, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.removeClass($strikethrough, "k_edit_tools_hlight");
        }
        let $superscript = this.btnElMap["superscriptFn"];
        if (cssMap["vertical-align"] === "super") {
            $B.DomUtils.addClass($superscript, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.removeClass($superscript, "k_edit_tools_hlight");
        }
        let $subscript = this.btnElMap["subscriptFn"];
        if (cssMap["vertical-align"] === "sub") {
            $B.DomUtils.addClass($subscript, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.removeClass($subscript, "k_edit_tools_hlight");
        }
        let $fontFamily = this.btnElMap["fontFamilyFn"];
        if (cssMap["font-family"]) {
            let v = cssMap["font-family"].replaceAll("\"", "");
            let comparev = v.replaceAll(/,\s+/g, ",");
            comparev = comparev.replaceAll(/\s+/g, "").toLowerCase();
            let childs = this["$fontFamilyFn"].lastChild.children;
            for (let i = 0; i < childs.length; i++) {
                let cfv = $B.DomUtils.attribute(childs[i], "val").replaceAll(/,\s+/g, ",").replaceAll(/\s+/g, "").toLowerCase();
                if (cfv.indexOf(comparev) >= 0) {
                    v = childs[i].innerText;
                    break;
                }
            }
            $fontFamily.firstChild.innerText = v;
        } else {
            $fontFamily.firstChild.innerText = $B.DomUtils.attribute($fontFamily.firstChild, "label");
        }

        let $fontSize = this.btnElMap["fontSizeFn"];
        if (cssMap["font-size"]) {
            $fontSize.firstChild.innerText = cssMap["font-size"];
        } else {
            $fontSize.firstChild.innerText = $B.DomUtils.attribute($fontSize.firstChild, "label");
        }
        let $fontTitle = this.btnElMap["fontTitleFn"];
        let txt = $B.DomUtils.attribute($fontTitle.firstChild, "label");
        if (cssMap["font-weight"] !== "400") {
            //轮询列表取值
            let childs = this["$fontTitleFn"].lastChild.children;
            for (let i = 0; i < childs.length; i++) {
                if (cssMap["font-size"] === $B.DomUtils.attribute(childs[i], "val")) {
                    txt = childs[i].innerText;
                    break;
                }
            }
        }
        $fontTitle.firstChild.innerText = txt;

        let $fontColor = this.btnElMap["fontColorFn"];
        $fontColor.lastChild.style.backgroundColor = cssMap["color"];

        let $backgroundColor = this.btnElMap["backgroundColorFn"];
        $backgroundColor.lastChild.style.backgroundColor = cssMap["background-color"];


        let $alignCenter = this.btnElMap["alignCenterFn"];
        if (cssMap["text-align"] === "center") {
            $B.DomUtils.addClass($alignCenter, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.removeClass($alignCenter, "k_edit_tools_hlight");
        }

        let $alignLeft = this.btnElMap["alignLeftFn"];
        if (cssMap["text-align"] === "left") {
            $B.DomUtils.addClass($alignLeft, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.removeClass($alignLeft, "k_edit_tools_hlight");
        }

        let $alignRight = this.btnElMap["alignRightFn"];
        if (cssMap["text-align"] === "right") {
            $B.DomUtils.addClass($alignRight, "k_edit_tools_hlight");
        } else {
            $B.DomUtils.removeClass($alignRight, "k_edit_tools_hlight");
        }
    }
    destroy() {
        this.colorIns = undefined;
        this.editIns = undefined;
        $B.DomUtils.remove(this.$tip);
        for (let i = 0; len = this.$panels.length; i++) {
            $B.DomUtils.remove(this.$panels[i]);
        }
        for(let i =0 ; i < this.BUICTLS.length ;i++){
            this.BUICTLS[i].destroy();
        }
        super.destroy();
    }
}
class URDO extends $B.BaseControl {
    constructor(editor) {
       super();
       this.editIns = editor;
       this.undoStack = new Stack(editCfg.undoSize);
       this.redoStack = new Stack(editCfg.undoSize);
       this.$undoBtn = this.editIns.toolIns.btnElMap["undoFn"];
       this.$redoBtn = this.editIns.toolIns.btnElMap["redoFn"];
    }
    /**
     * 响应按钮undo
     */
    undoFn(){
        console.log("exe undo....");
        let data = this.undoStack.pop();
        this.exeFn(data,()=>{
            this.exeUndo(data);
        });
    }
    /**
     * 响应按钮redo
     */
    redoFn(){
        console.log("exe redo....");
        let data = this.redoStack.pop();
        this.exeFn(data,()=>{
            this.exeRedo(data);
        });
    }
    /**
     * 优先执行非默认处理
     * **/
    exeFn(data,exeCallFn){
        let action = data.action;
        if(this[action]){
            this[action](data);
        }else{
            exeCallFn();
        }
    }
    /**
     * 清空重做记录
     */
    clearRedoRec(){
        this.redoStack.clear();
        this.reativeUI();
    }
    /**
     * 创建一个重做记录
     * **/
    makeRedo(fn,params){
        this.redoData = this.makeData(fn);
    }
    /**
     * 创建一个撤销记录    
     */
    makeUndo(fn,params){  
        if(!this.undoData){            
            this.undoData = this.makeData(fn,params);
        }
    } 
    /**
     * 将当前重做记录放入重做栈
     * **/
    putCurRedo(redoData){
        let rData = redoData ? redoData : this.redoData;
        if(rData){
            this.redoStack.push(rData);
            this.reativeUI();
            this.redoData = undefined;
        }
    }
    /**
     * 创建一个记录
     * fn可以是一个字符串也可以是一个段落元素
     */   
    makeData(fn,params){
        let bakHtml = [],
            action,
            region,
            isStr = typeof fn === "string";
        if(!isStr && $B.Dom.isElement(fn)){
            let pid = fn.id;
            let firstEl = fn.firstChild;
            while(firstEl){
                if($B.Dom.hasClass(firstEl,"p_span")){
                    break;
                }
                firstEl = firstEl.firstChild;
            }
            let spanId = firstEl.id;
            region =  {
                "isCollapsed": true,
                "startPel": pid,
                "endPel": pid,
                "startSpan": spanId,
                "endSpan": spanId,
                "startIdx": 1,
                "endIdx": 1,
                "dirStrtId": pid,
                "dirEndId": pid
            };
            bakHtml.push(fn.outerHTML);
        }else{
            region =  this.copyRegion(); 
            if(isStr && fn === "clearFn"){ //全部清空
                bakHtml.push(this.editIns.$input.innerHTML);
                action = 'recovAll';
            }else if(isStr && fn === "recovAll"){
                action = 'clearFn';
            }else if(region){
                let $p = $B.Dom.children(this.editIns.$input,"#" + region.startPel);
                if(region.startPel != region.endPel){                
                    let $p1 = $B.Dom.children(this.editIns.$input,"#" + region.endPel);
                    while($p){
                        bakHtml.push($p.outerHTML);
                        if($p === $p1){
                            break;
                        }
                        $p =  $p.nextSibling;
                    }                
                }else{
                    bakHtml.push($p.outerHTML);
                }
            }
        }      
        return  {
            action: action,
            bakHtml:bakHtml,
            region: region    
        };
    }
    copyRegion(){
        try{
            let region =  this.editIns.getRegion();
            return {
                "isCollapsed": region.isCollapsed,
                "startPel": region.startPel,
                "endPel": region.endPel,
                "startSpan": region.startSpan,
                "endSpan": region.endSpan,
                "startIdx": region.startIdx,
                "endIdx": region.endIdx,
                "dirStrtId": region.dirStrtId,
                "dirEndId": region.dirEndId
            };
        }catch(e){
            console.log(e);
            return;
        }       
    }
    /**
     * 将当前撤销记录放入栈中
     */
    putCurUndo(undoData){
        let uData = undoData ? undoData :this.undoData;
        if(uData){           
            this.undoStack.push(uData);
            this.reativeUI();
            this.undoData = undefined;
        }
    }
    /**
     * 联动撤销，重做UI按钮
     */
    reativeUI(){
        if(this.undoStack.length > 0){
            $B.Dom.removeClass(this.$undoBtn,"k_edit_tools_disabled");
        }else{
            $B.Dom.addClass(this.$undoBtn,"k_edit_tools_disabled");
        }
        if(this.redoStack.length > 0){
            $B.Dom.removeClass(this.$redoBtn,"k_edit_tools_disabled");
        }else{
            $B.Dom.addClass(this.$redoBtn,"k_edit_tools_disabled");
        }
    }
    /**
     * 恢复所有(清空的撤销)
     * **/
    recovAll(data){
        let bakHtml = data.bakHtml;
        this.editIns.$input.innerHTML = bakHtml.join("");
        if(data.region){
            this.editIns.rebuildRegion(data.region);
        }       
        this.makeRedo("recovAll");
        this.putCurRedo();
        this.reBindEvents(this.editIns.$input);
    }
    /**
     * 执行清空
     */
    clearFn(){
        this.editIns._clearFn();
    }
    /**
     * 执行通用撤销 
     */
    exeUndo(data){
        console.log("执行通用撤销>>>>>>>>>yt>>",data);      
        let rdData = this.execomm(data);
        this.putCurRedo(rdData);
    }
    /**
     * 执行通用重做
     */
    exeRedo(data){
        console.log("执行通用重做>>>>>>>>>>>",data);
        let rdData = this.execomm(data);
        this.putCurUndo(rdData);
    }
    /**
     * 通用执行
     * **/
    execomm(data){
        let region = this.copyRegion();
        let bakHtml = data.bakHtml;
        let $input = this.editIns.$input;
        let saveHtml = [],$preEl;
        let reg = /^k_\d+/;
        for(let i =0 ;i < bakHtml.length ;i++){
            let html = bakHtml[i];
            if(reg.test(html)){
                let rmEl =  $B.Dom.children($input,"#"+html);
                saveHtml.push(rmEl.outerHTML);
                $B.Dom.remove(rmEl);
                continue;
            }
            let $el = $B.Dom.createEl(html);
            let style = $B.Dom.attr($el,"style");
            let id = $el.id;
            let replaceEl = $B.Dom.children($input,"#"+id);
            let isNew = false;
            if(replaceEl){
                saveHtml.push(replaceEl.outerHTML);
                replaceEl.innerHTML= $el.innerHTML ;
            }else{                
                replaceEl = $el;
                isNew = true;
                saveHtml.push(id);
            }
            $B.Dom.attr(replaceEl,{"style":style});
            if(isNew){
                $B.Dom.after($preEl,replaceEl);
            }
            $preEl = replaceEl;
            this.reBindEvents(replaceEl);
        }
        let rdData = { 
            bakHtml:saveHtml,
            region: region 
        };
        try{
            if(data.region){
                this.editIns.rebuildRegion(data.region);
            }            
        }catch(e){
            console.log(e);
            console.log(data);
        }
        return rdData;
    }
    reBindEvents(el){
       this.editIns.tableIns.bindEventsExt(el);
    }
}

 
 if(!window["$B"] ) {window["$B"] = $B;} 
  return window["$B"] ; 
});
